DAILY NEWS

Stay Ahead, Stay Informed – Every Day

Advertisement
How I Discovered and Deobfuscated a Hidden PHP Backdoor on My Server


As developers and system architects, we often secure our code but neglect the silent threats lurking in old directories or clever obfuscations. Recently, I caught a stealthy PHP backdoor ((random_name).php) embedded in a system.

Instead of just deleting it, I decided to perform a full reverse engineering to understand exactly how it works, how it bypasses scanners, and how it maintains persistence on a server.

Here is a quick summary of what I found during the analysis.

πŸ” The Anatomy of the MalwareAt first glance, the file was heavily obfuscated using multiple layers of encoding to look like harmless gibberish. However, the core mechanism relied on a classic but dangerous pattern:

PHP// The malicious pattern used to execute hidden codeeval(base64_decode($_POST(‘encoded_payload’)));Key Techniques Used by the Attacker:Layered Obfuscation: The code utilized deep base64 nesting combined with string manipulation functions to evade signature-based security scanners.

Hidden Tar Extraction: Deep inside the encoded strings, the malware contained a compressed TAR structure. Once triggered, it extracts a full-featured web shell into the server directories.

SSH Persistence: The ultimate goal wasn’t just to execute commands onceβ€”the script was designed to inject malicious public keys into the server’s ~/.ssh/authorized_keys file, granting the attacker permanent, direct SSH access without leaving a footprint in the web logs.

πŸ› οΈ How to Protect Your SystemIf you suspect your server has been compromised, simply deleting the .php file might not be enough. You need to:

Check your ~/.ssh/authorized_keys for unauthorized entries.

Audit your system cronjobs to ensure the malware doesn’t have a re-infection script scheduled.

Implement strict file permissions (chmod 644 for files, 755 for directories) and disable dangerous PHP functions like eval(), exec(), and passthru() in your php.ini.

πŸ“– Read the Full Deep DiveI have documented the complete step-by-step deobfuscation process, the code breakdown, directory structures, and full remediation steps on GitHub.

πŸ‘‰ See full analysis and source code breakdown here:

https://github.com/KhaiTrang1995/Malware-Analysis-Reports-PHP-Backdoor

Alternatively, you can view the repository directly:

Tags: #php #security #devsecops #malware



Source link

Every AI coding assistant is shipping the same security bugs.



*Not a promo.. I mean why would anyone promote something free, actually looking to get some contributors to help us seal sone holes of ai-coded products and encourage founders of ai-written products to respect security and privacy.*

So, here it goes.. Nowadays many of us are building with Claude Code, Copilot, Cursor, Codex, Gemini, or any AI coding assistant, this is worth running against your project. – To be honest, I did think of building a tool around this, but it doesn’t sound nice to monetize on vulnerabilities for me, nor do I see much logic having a ‘blackbox’ that allegedly scans your projects. We’re talking about security here, so IMO such things should be open source and allow contributions.

And of course – my good friend AI helped me speed up the shipment of this repo πŸ™‚

Some of most common things that appear :

JWT secrets set to “secret” or “changeme”

API keys in NEXT_PUBLIC_ env vars, fully exposed to the browser
User input going directly into system prompts via string interpolation
Vector databases using one shared namespace for all users β€” any user’s RAG query can
surface another user’s documents
Agents handed child_process access with no scope restrictions

These aren’t obscure edge cases, this is how most of AI-generated code comes out, if you allow it to produce HUGE chunks instead of targeted and controlled ai-coding. Even knowing tons about security and vulnerabilities, having AI write code might still expose you to some common cases.

The problem with existing references

OWASP, NIST, and CWE are good. They were written for a world where developers wrote most of their code by hand. They don’t cover MCP tool poisoning, cross-agent prompt injection, or what happens when your agent’s long-term memory accepts unsanitized writes. Ok, that’s not entirely true – today AI-generated code is allover the place, so we see more and more tools to review the code, etc, but many are paid and/or complicated which is an entry barrier for a vibe coder.

What I and few AIs shipped

A 258-item checklist across 17 categories, with a detection method for every item: static grep or AST pattern, runtime test, or config inspection. Severity rated. 33 items in Category 6 specifically cover LLM integration vulnerabilities that don’t appear elsewhere.

More usefully: a companion prompt.md that turns the full checklist into a structured codebase scan you can run in one command.

Running it

From your project root, with Claude Code installed:

claude “$(curl -s https://raw.githubusercontent.com/a-leks/genai-app-security-checklist/main/prompt.md)”

Enter fullscreen mode

Exit fullscreen mode

With Gemini CLI:

gemini “$(curl -s https://raw.githubusercontent.com/a-leks/genai-app-security-checklist/main/prompt.md)”

Enter fullscreen mode

Exit fullscreen mode

The model reads your codebase, runs all 258 checks, and returns a markdown report with severity, file path, line number, code snippet, and a specific remediation for each finding.

What the output looks like

### (6.1) Prompt injection β€” user input in system prompt
– Severity: Critical
– File: app/api/chat/route.ts
– Line: 34
– Snippet:
const systemPrompt = `You are a helpful assistant. User context: ${req.body.userBio}`
– Remediation: Move user-supplied content to the user message role, never system.
Strip prompt control characters before passing any user string to the model.

Enter fullscreen mode

Exit fullscreen mode

The LLM-specific items worth knowing

6.26 β€” MCP tool poisoning. If your agent uses third-party MCP servers, tool results from those servers enter the agent’s context as trusted input. An attacker who controls one of those servers can inject instructions through it.

6.27 β€” Agent memory poisoning. Whatever your agent writes to long-term memory gets read back in future sessions. If malicious content reaches that memory store, it executes next time the agent retrieves it.

6.30 β€” Cross-agent prompt injection. In multi-agent systems, output from Agent A becomes input to Agent B. If an attacker can influence Agent A’s output, Agent B processes the attack payload without knowing its origin is untrusted.

Where to find it

https://github.com/a-leks/genai-app-security-checklist

Apache 2.0. Contributions welcome β€” especially new LLM attack patterns with detection methods and real-world references.



Source link

Cookie based authentication & authorization in ASP.NET Core explained


Video – https://youtu.be/GhZLi8pBJow?si=mnIVpCke9OJBMFoJ

Services for Authentication and Authorization

Authentication Service

Maintains multiple authentication schemes
Uses Cookie handler to Build ClaimsPrincipal from cookie, set up request redirection for login, logout, access denial
Add cookie authentication service in DI container using the following

// Add Cookie Authentication service
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.LoginPath = “/Account/Login”; // Specify the path to the login page
options.AccessDeniedPath = “/Account/AccessDenied”; // Specify the path for access denied
options.ExpireTimeSpan = TimeSpan.FromMinutes(60); // Set the cookie expiration time
options.SlidingExpiration = true; // Enable sliding expiration
});

Enter fullscreen mode



Exit fullscreen mode

AddAuthentication adds the authentication service to DI container. It also specifies the default authentication scheme (Cookies) for authentication.
AddCookie provides a cookie authentication handler for the Cookies authentication scheme.

Authorization Service

Evaluates ClaimsPrincipal’s claims against authorization policies to determine if the request is authorized
Add authorization service in DI container using the following

builder.Services.AddAuthorization(options =>
{
// Define a rule named “AdminOnly”
options.AddPolicy(“AdminOnly”, policy =>
policy.RequireRole(“Admin”)
.RequireClaim(“EmployeeId”));
});

Enter fullscreen mode



Exit fullscreen mode

The above code adds a policy named AdminOnly along with default available authorization service policies

A Request’s Journey for cookie-based Authentication and Authorization in dotnet

Phase 1 – Authentication middleware (for Identification)

Authentication middleware identifies the visitor by extracting the ClaimsPrincipal from cookie and attaches it to HttpContext

Authenticaiton middleware is added to the request pipeline using the following

app.UseAuthentication();

Enter fullscreen mode



Exit fullscreen mode

Steps

Middleware asks the Authentication Service (configured via AddAuthentication) for a ClaimsPrincipal (user).
Authentication Service calls the Cookie Handler. It decrypts the cookie (using Data Protection Provider) and creates a ClaimsPrincipal
The created ClaimsPrincipal is attached to HttpContext.User. The request moves to the next middleware.

Phase 2: Authorization middleware (for Permissions check)

Authorization middleware evaluates the identified ClaimsPrincipal’s claims and redirects the request to login or denies the request if claims don’t meet the authorization requirements
Authorization middleware is added to the request pipeline using the following

app.UseAuthorization();

Enter fullscreen mode



Exit fullscreen mode

Steps

Authorization middleware checks the endpoint for attributes like (Authorize) or a specific policy (e.g., (Authorize(Policy = “AdminOnly”))).
Authorization middleware asks the Authorization Service (registered via AddAuthorization) to evaluate the ClaimsPrincipal’s claims against those rules.
Based on that evaluation, the system executes one of three paths:

Path A: User is Not Logged In (Challenge the request)

Condition: The authorization policy requires a user, but HttpContext.User is anonymous.
Action: The Authorization middleware triggers a Challenge by calling the ChallengeAsync method on the Authentication service.
Execution: Authentication service delegates the Challenge execution to Cookie Handler, which modifies HttpContext.Response for a 302 Redirect to LoginPath. The pipeline short-circuits.

Path B: User has Wrong Permissions (Forbid the request)

Condition: ClaimPrincipal is present, but the claims fail the requirements of authorization policies.
Action: The Authorization middleware triggers a Forbid by calling the ForbidAsync method on the Authentication service.
Execution: Authentication service delegates the Forbid execution to Cookie Handler, which modifies HttpContext.Response for a 302 Redirect to AccessDeniedPath. The pipeline short-circuits.

Path C: Access Granted

Condition: The user’s claims satisfy all requirements in the Authorization Service.
Execution: The middleware calls next(), allowing the request to reach next middleware (like controllers).

Setting logged in user in the cookie

The user will submit credentials in the login page
The user credentials will be verified from a database and ClaimsPrincipal will be created to represent the logged in user
HttpContext.SignInAsync uses Authentication service’s Cookie Handler to set the logged in user details (a ClaimsPrincipal) in the response cookie

await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
authProperties);

Enter fullscreen mode



Exit fullscreen mode

Signout logged in user

await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);

Enter fullscreen mode



Exit fullscreen mode

HttpContext.SignOutAsync uses Authentication service’s Cookie Handler to expire the cookie that contains the logged in user details (a ClaimsPrincipal) and makes the HttpContext.User as anonymous

Access the ClaimsPrincipal (logged in user)

After the authentication middleware derives a valid ClaimsPrincipal from the cookie, it sets the user details (ClaimsPrincipal) in the HttpContext.User object
Hence

HttpContext.User?.Identity?.IsAuthenticated can be used to determine if a request is authenticated
HttpContext.User.Identity.Name can be used to determine the logged in user name



Source link