New Container, Old Code: Web Shell Persists Three Months in 1C-Bitrix Environment

Two 1C-Bitrix sites shared a web shell named WebShellOrb after an attacker exploited multiple vulnerabilities in a custom appeal application. The initial compromise went undetected because Nginx logs were retained for only one month, leading responders to conclude that no scanning activity remained visible. After agents showed no malicious code, administrators restarted the container without addressing the underlying issues in the shared filesystem and source code. The attacker regained access weeks later by reusing JWT tokens generated with a hardcoded secret and by exploiting SQL injection flaws that allowed password hash extraction. Shared system user accounts and a common filesystem volume enabled the shell to propagate between sites and survive container recreation. The incident highlighted that redeploying containers and rotating passwords failed to eliminate persistence rooted in unpatched code and misconfigured authentication logic.

HabrTranslated from Russian

Read at source

Security researchers have detailed a prolonged intrusion into two 1C-Bitrix websites where a web shell called WebShellOrb reappeared three months after the initial incident was declared closed. The sites, named appeal and new, ran on shared infrastructure that preserved attacker access despite container restarts.

Logs from Nginx first revealed the compromise through repeated POST requests to /assets/images/access.php followed by GET requests to a hashed index.php file, with the shell itself acting as the referrer. Because logs were kept for only thirty days, investigators found no evidence of the initial scanning or exploitation phase and incorrectly assumed the breach occurred outside the retention window.

Checks of 1C-Bitrix agents returned no suspicious entries, prompting the team to restart the container. The attacker returned shortly afterward, demonstrating that the root cause remained untouched in the application code and shared storage.

Attack chain and vulnerabilities

The intrusion progressed through several weaknesses in the custom appeal application:

  • SQL injection in AppealModel::getReportData() that bypassed protection when the $isSkipArgs flag was set to true.
  • Authentication bypass in login and logout routes because JWT token validation was never enforced in Identity.php.
  • Exposure of password hashes through User.php methods that included the password field and always returned the record for user ID 5.
  • A hardcoded JWT secret stored in plain text within the configuration file.

After obtaining access via /api/auth/login, the attacker performed bulk data exfiltration using a single get-list request and later triggered an SQL injection through /api/appeal/get-report. Multiple web shells were then uploaded to /assets/images/ on the appeal site and copied to the new site over the shared filesystem.

Even after the container was recreated and administrator passwords changed, the attacker retained access because the JWT secret had not been rotated and the authentication bypass remained in place. The shared system user and common volume allowed the shell files to persist and spread between the two applications.

Investigators concluded that effective remediation required parameterizing SQL queries, removing the skipArgs() bypass, enforcing token validation, moving the JWT secret to environment variables, excluding password fields from API responses, and separating filesystem and user contexts between sites.

Meridian digestThe week's most consequential security stories, distilled into one briefing.See the digest

More in Data Breaches & Leaks

How to Check If Your Passwords Have Leaked Online Using Have I Been Pwned
Yandex Restores Access to 96% of Yandex Disk Data After Data Center Attacks
k0t Operators Breach Corporate Firewalls and VPNs Exposing Over 70,000 Credentials