Atomic Arch: AUR Package Takeover Delivers Infostealers and eBPF Rootkits
Attackers adopted orphaned Arch User Repository (AUR) packages using forged commit signatures to inject npm and bun dependency executions. The rogue packages 'atomic-lockfile' and 'js-digest' delivered a Rust credential stealer, systemd persistence, and an eBPF rootkit.
On this page 0% read
Executive Summary
Between June 9 and June 12, 2026, a widespread supply chain campaign named “Atomic Arch” targeted the Arch User Repository (AUR) community [Sources 1, 3, and 4]. By exploiting the AUR’s open adoption workflow for orphaned packages, attackers took ownership of more than 400 community-contributed packages [Sources 3 and 4].
The attackers utilized forged git commit signatures to impersonate trusted maintainers—most notably forging commits under the identity of legitimate developer arojas [Sources 3 and 6]. The tampered packages were modified to fetch and execute rogue npm/bun modules: first deploying atomic-lockfile via npm and later transitioning to js-digest via bun [Sources 1, 3, and 4]. Both modules carried a compiled Rust-based Linux ELF executable designed to exfiltrate developer secrets, browser cookies, SSH keys, Discord sessions, and Vault secrets [Sources 1 and 2].
Responders should note that if these packages were built or installed with root privileges (e.g. running an AUR helper like yay or paru under sudo), the payload deployed an eBPF-based rootkit [Sources 2 and 4]. This rootkit hooks system calls to hide process IDs, files, and socket connections, rendering standard process monitoring utilities like ps, top, and netstat blind [ioctl.fail]. Consequently, compromised systems must be treated as untrusted, and full reinstallation from clean media is strongly recommended [Sources 1 and 4].
Key Facts
| Fact | Value |
|---|---|
| Threat Type | AUR package takeover supply chain attack |
| Ecosystem | aur, arch, npm, bun |
| Campaign Name | Atomic Arch |
| Disclosed Date | 2026-06-11 |
| Execution Trigger | PKGBUILD build-time dependency execution / install scripts |
| Malicious Packages | atomic-lockfile, js-digest |
| Malicious Versions | atomic-lockfile@1.4.2, js-digest@1.0.0 |
| Primary Exfiltration | olrh4mibs62l6kkuvvjyc5lrercqg5tz543r4lsw3o6mh5qb7g7sneid[.]onion |
Evidence Assessment
- confirmed: The Arch User Repository maintainers confirmed the campaign, removed compromised versions, and flagged multiple malicious maintainer accounts:
krisztinavarga,custodiatovar, andveramagalhaes[Sources 1, 3, and 4]. - confirmed: Developer David Runge and community audits proved that commits referencing legitimate KDE developer
arojaswere forged using git commit metadata signature manipulation to disguise ownership takeovers [Sources 3 and 6]. - confirmed: Detailed reverse engineering from ioctl.fail mapped the Rust credential-stealing payload (
deps), C2 exfiltration routes over Tor onion domains (olrh4mibs62l6kkuvvjyc5lrercqg5tz543r4lsw3o6mh5qb7g7sneid[.]onion), and the exact directory locations of the eBPF rootkit maps [ioctl.fail]. - likely: The use of
/usr/bin/monero-wallet-guichecks inside the infostealer indicates the attackers planned to deploy cryptominers or steal Monero wallet data from targeted developer workstations [ioctl.fail]. - not_observed: No compromises of upstream official Arch Linux software repositories (
[core],[extra]) or official package databases were identified during this campaign [Sources 1 and 4].
Impact Determination
| Classification | Criteria | Required evidence | Handling decision | Closure condition |
|---|---|---|---|---|
| Confirmed compromise | An affected AUR package was installed and execution of npm or bun malicious sub-packages is logged or eBPF maps exist. | systemd unit files, /sys/fs/bpf/hidden_* existence, or deps execution logs. | Isolate the host, boot from clean media to verify filesystem, rotate all keys, and regenerate SSH identities. | Clean OS install verified, all passwords changed, SSH keys rotated. |
| Presumed exposed | Compromised AUR package name and version installed within the June 9–12 window, but execution logs are unavailable. | pacman transaction logs (pacman.log), ~/.npm/_cacache/ or ~/.bun/ cache directories. | Assume all secrets accessible on the developer endpoint have been exfiltrated. Revoke API tokens immediately. | Dependency verification clean, credential rotation complete. |
| Potentially exposed | Listed AUR packages exist in system but timestamps do not match the campaign window. | Package installation metadata from pacman -Qi. | Check PKGBUILD diff history for unexpected npm/bun executions. | Audit confirmation showing no malicious hook installation. |
| Not exposed | No compromised packages installed, and local caches are clean. | Negative results on scanner script run. | No action required. Document negative result. | Case file closure. |
| Unknown | System logs or developer workstations are missing local telemetry. | Gaps in endpoint logs. | Execute proactive rotation of high-value credentials that had write access from this endpoint. | Telemetry gaps resolved or credentials fully rotated. |
Minimum Evidence To Collect
- Pacman transaction logs: normally located at
/var/log/pacman.log. Collecting these logs is relevant because it records the exact timestamps of package installations (likealvrornodejs-elm), helping to resolve if the system was modified during the compromise window. - NPM cache metadata: normally located under
~/.npm/_cacache/. Collecting this cache is relevant because it captures metadata of external packages likeatomic-lockfiledownloaded during AUR builds, proving if a compromised payload was fetched. - Bun installation cache: normally located under
~/.bun/install/cache/. Collecting this cache is relevant because it records Bun dependency history such asjs-digest, helping to confirm the presence of rogue modules. - BPF filesystem mount: normally located at
/sys/fs/bpf/. Check if any pinned eBPF maps (hidden_pids,hidden_names,hidden_inodes) exist, which is relevant because their presence proves active kernel-level rootkit evasion. - Systemd service definitions: normally located at
/etc/systemd/system/and~/.config/systemd/user/. Inspecting active service files is relevant because the rootkit configures persistence with aggressive autorestart limits.
Timeline
- 2026-06-09T00:00:00Z: Attackers begin pushing forged commits to adopt orphaned packages. The account
krisztinavargapushes the malicious update to thealvrpackage [Sources 1, 3]. - 2026-06-11T12:00:00Z: Initial reports of anomalous dependencies appear on the Arch General mailing list [lists.archlinux.org].
- 2026-06-11T18:00:00Z: Security analysis site ioctl[.]fail publishes a preliminary teardown of the Rust stealer and eBPF hook behaviors [ioctl.fail].
- 2026-06-12T08:00:00Z: Attackers shift tactics to Bun-based
js-digestwave using accountscustodiatovarandveramagalhaes[Sources 1, 4]. - 2026-06-12T14:00:00Z: Legitimate maintainers verify forged commit author metadata impersonating
arojas[chaos.social]. - 2026-06-12T18:00:00Z: AUR admins purge the compromised packages and accounts. Community detection repositories go live [Sources 1, 4].
What Happened
The attack utilized the trusted nature of community-built AUR helper environments. When an orphaned package is adopted on the AUR, there is no automatic warning sent to existing users. The attackers took over these packages and updated the PKGBUILDs. By configuring the installation lifecycle (via preinstall or .install hooks) to run npm install atomic-lockfile or bun install js-digest, they forced package managers to download external javascript dependencies during compilation [Sources 1 and 2].
The javascript dependencies contained a preinstall script that executed a native binary named deps [ioctl.fail]. This binary compiled in Rust searched for credential stores and exfiltrated them to temp[.]sh or a Tor hidden service [ioctl.fail]. If elevated system administration capabilities (such as CAP_BPF or CAP_SYS_ADMIN) were available, the payload mounted /sys/fs/bpf and pinned eBPF maps to hook processes, filesystem directories, and network connections, making the intrusion invisible to local system administrators [Sources 2 and 4].
Technical Analysis
Package Manipulation
The attackers adopted orphaned AUR packages using forged commit signatures impersonating trusted maintainer arojas [Sources 3 and 6]. The tampered package PKGBUILD files were modified to fetch and execute rogue npm/bun dependency sub-packages atomic-lockfile and js-digest during the package build process [Sources 1, 3, and 4]. These malicious sub-packages delivered the Rust credential stealer payload [Sources 1 and 2].
Execution And Collection
The execution chain is triggered by running makepkg or an AUR helper like yay. The installer invokes npm or bun, which runs the pre-install script ./src/hooks/deps. Once active, the Rust binary collects:
- Discord, Telegram, and Slack session tokens.
- Personal Access Tokens and SSH keys for Git.
- Credentials stored in web browser cookies and sqlite profiles.
- AWS, GCP, and Docker credentials.
- Filesystem paths containing crypto wallets.
Exfiltration
The primary exfiltration channel utilized a bundled local Tor SOCKS proxy transport to connect to the Tor hidden service olrh4mibs62l6kkuvvjyc5lrercqg5tz543r4lsw3o6mh5qb7g7sneid[.]onion [ioctl.fail]. In cases where Tor connectivity failed, the payload fell back to uploading collected archives via HTTP POST to hxxps://temp[.]sh/upload [ioctl.fail].
Affected Assets and Blast Radius
The compromise of developer workstations poses a high blast radius due to exfiltrated credentials. The exposure path analysis maps the compromised identities to downstream registries, repositories, and cloud ecosystems.
| Affected Asset | Targeted Environment | Compromise Impact |
|---|---|---|
| Arch Developer Workstations | Local machines running tampered AUR helpers | High-privilege workstation hijack, credential collection |
| Git / GitHub Accounts | Organization repositories and workflows | Exfiltration of PATs and SSH keys, potential supply chain propagation |
| NPM / PyPI Registries | Package publishing systems | Hijack of publishing tokens, enabling downstream package tampering |
| Cloud Infrastructures | AWS, GCP, and Azure accounts | API keys and session tokens exfiltrated, exposing cloud resources |
| Cryptocurrency Wallets | Local wallet configurations (Exodus, Monero) | Direct theft of stored cryptocoins |
Indicators of Compromise
Below is a consolidated list of the known compromised AUR packages hijacked during the Atomic Arch campaign. If any of these packages are installed on your system or present in your package build cache (e.g. ~/.cache/yay/ or ~/.cache/paru/), check their git logs and look for unexpected npm or bun dependency commands inside the PKGBUILD file.
Compromised Packages
| Name | Source / Wave |
|---|---|
atomic-lockfile@1.4.2 | npm dependency wave [Sources 1, 3] |
js-digest@1.0.0 | bun dependency wave [Sources 1, 4] |
alvr | Tampered AUR package [Sources 1, 3] |
guiscrcpy | Tampered AUR package [Sources 1, 4] |
netmon-git | Tampered AUR package [Sources 1, 4] |
inadyn-mt | Tampered AUR package [Sources 1, 4] |
nodejs-elm | Tampered AUR package [Sources 1, 3] |
keepassx2 | Tampered AUR package [Sources 1, 4] |
Network Indicators
- Onion address:
olrh4mibs62l6kkuvvjyc5lrercqg5tz543r4lsw3o6mh5qb7g7sneid[.]onion - Fallback URL:
hxxps://temp[.]sh/upload - Payload URL:
olrh4mibs62l6kkuvvjyc5lrercqg5tz543r4lsw3o6mh5qb7g7sneid[.]onion/bin/linux
File and Hash Indicators
/sys/fs/bpf/hidden_pids(eBPF map file)/sys/fs/bpf/hidden_names(eBPF map file)/sys/fs/bpf/hidden_inodes(eBPF map file)/usr/bin/monero-wallet-gui(attacker file query check)6144d433f8a0316869877b5f834c801251bbb936e5f1577c5680878c7443c98b(atomic-lockfile payload hash)7883bda1ff15425f2dbe622c45a3ae105ddfa6175009bbf0b0cad9bf5c79b316(js-digest payload hash)47893d9badc38c54b71321263ce8178c1abb10396e0aadf9793e61ec8829e204(fallback cryptominer payload hash)
Detection and Hunting
Hunt Manifest: atomic-arch-aur-compromise-ebpf-maps
- Title: Detect Atomic Arch Pinned eBPF Maps
- Question: Did the rootkit pin its known eBPF maps to the BPF virtual filesystem?
- Telemetry Family: linux-filesystem
- Telemetry Context: trusted recovery environment or root shell
- Positive Signal: At least one documented pinned eBPF map exists in /sys/fs/bpf/
- False Positives: None known for these specific map names.
- Classification on Match: confirmed_compromise
#!/usr/bin/env python3
"""Detect Atomic Arch pinned eBPF maps.
Exit codes:
0: Clean (no maps found)
1: Compromise (at least one map found)
2: Execution error
"""
import os
import sys
import argparse
MAP_NAMES = ["hidden_pids", "hidden_names", "hidden_inodes"]
def main():
parser = argparse.ArgumentParser(description="Scan for pinned eBPF maps")
parser.add_argument("--bpf-dir", default="/sys/fs/bpf", help="BPF directory path")
args = parser.parse_args()
bpf_dir = args.bpf_dir
if not os.path.exists(bpf_dir):
print(f"[-] BPF directory '{bpf_dir}' does not exist.")
return 0
found = []
for name in MAP_NAMES:
target = os.path.join(bpf_dir, name)
if os.path.exists(target):
print(f"[!] MALICIOUS: Pinned eBPF map '{name}' found at '{target}'")
found.append(target)
if found:
return 1
print("[+] No malicious pinned eBPF maps found.")
return 0
if __name__ == "__main__":
try:
sys.exit(main())
except Exception as e:
print(f"[-] Execution failure: {e}", file=sys.stderr)
sys.exit(2)
Hunt Manifest: atomic-arch-aur-compromise-package-caches
- Title: Detect Tampered Package Manager Caches
- Question: Are the compromised dependency packages atomic-lockfile or js-digest cached on this workstation?
- Telemetry Family: linux-filesystem
- Telemetry Context: developer home directories
- Positive Signal: Cached files containing references to atomic-lockfile or js-digest exist in NPM or Bun caches.
- False Positives: Developer intentionally researching the malware in a sandbox.
- Classification on Match: presumed_exposed
#!/usr/bin/env python3
"""Check NPM and Bun cache directories for compromised dependency packages.
Exit codes:
0: Clean (no indicators found)
1: Compromise (indicators found)
2: Execution error
"""
import os
import sys
import argparse
from pathlib import Path
TARGETS = ["atomic-lockfile", "js-digest"]
def main():
parser = argparse.ArgumentParser(description="Scan NPM and Bun cache directories")
parser.add_argument("--npm-cache", default=os.path.expanduser("~/.npm/_cacache"), help="Path to NPM cache")
parser.add_argument("--bun-cache", default=os.path.expanduser("~/.bun/install/cache"), help="Path to Bun cache")
args = parser.parse_args()
found = False
# Check NPM cache
npm_path = Path(args.npm_cache)
if npm_path.exists() and npm_path.is_dir():
print(f"[+] Scanning NPM cache at: {npm_path}")
for root, _, files in os.walk(npm_path):
for file in files:
filepath = Path(root) / file
if filepath.is_file() and os.access(filepath, os.R_OK):
content = filepath.read_text(errors="ignore")
for target in TARGETS:
if target in content:
print(f"[!] MALICIOUS: Found NPM cache reference to '{target}' in '{filepath}'")
found = True
# Check Bun cache
bun_path = Path(args.bun_cache)
if bun_path.exists() and bun_path.is_dir():
print(f"[+] Scanning Bun cache at: {bun_path}")
for root, _, files in os.walk(bun_path):
for file in files:
filepath = Path(root) / file
if filepath.is_file() and os.access(filepath, os.R_OK):
content = filepath.read_text(errors="ignore")
for target in TARGETS:
if target in content:
print(f"[!] MALICIOUS: Found Bun cache reference to '{target}' in '{filepath}'")
found = True
if found:
return 1
print("[+] No indicators found in package caches.")
return 0
if __name__ == "__main__":
try:
sys.exit(main())
except Exception as e:
print(f"[-] Execution failure: {e}", file=sys.stderr)
sys.exit(2)
Hunt Manifest: atomic-arch-aur-compromise-systemd-persistence
- Title: Detect Suspicious Systemd Persistence Units
- Question: Did the malware configure a persistent systemd service with instant infinite restart logic?
- Telemetry Family: linux-filesystem
- Telemetry Context: systemd service directories
- Positive Signal: A systemd unit contains the exact Restart=always and RestartSec=30 parameters.
- False Positives: Legitimate local services configured with similar aggressive recovery limits.
- Classification on Match: presumed_exposed
#!/usr/bin/env python3
"""Check systemd unit directories for suspicious persistent services.
Exit codes:
0: Clean (no indicators found)
1: Compromise (indicators found)
2: Execution error
"""
import os
import sys
import argparse
from pathlib import Path
def main():
parser = argparse.ArgumentParser(description="Scan systemd services for persistence hooks")
parser.add_argument("--systemd-dirs", nargs="+", default=[
"/etc/systemd/system",
os.path.expanduser("~/.config/systemd/user")
], help="Systemd directories to scan")
args = parser.parse_args()
found = False
for directory in args.systemd_dirs:
dir_path = Path(directory)
if not dir_path.exists() or not dir_path.is_dir():
continue
print(f"[+] Scanning systemd directory: {dir_path}")
for file in dir_path.glob("*.service"):
if file.is_file() and os.access(file, os.R_OK):
content = file.read_text(errors="ignore")
if "Restart=always" in content and "RestartSec=30" in content:
if any(x in content for x in ["deps", "monero", "temp.sh", "onion"]):
print(f"[!] MALICIOUS: Suspicious systemd persistence hook found at '{file}'")
found = True
if found:
return 1
print("[+] No suspicious systemd units found.")
return 0
if __name__ == "__main__":
try:
sys.exit(main())
except Exception as e:
print(f"[-] Execution failure: {e}", file=sys.stderr)
sys.exit(2)
Hunt Manifest: atomic-arch-aur-compromise-ioc-scope-scan
- Title: Generic IOC file and log scope scan
- Question: Do local files or exported logs contain any IOC values listed for atomic-arch-aur-compromise?
- Telemetry Family: file-log
- Telemetry Context: repository trees, host filesystems, package caches, and exported logs
- Positive Signal: One or more exact IOC values from iocs.json matched file paths, file contents, or logs
#!/usr/bin/env python3
"""Generic IOC scope scanner for atomic-arch-aur-compromise.
Searches repository trees and exported logs for literal IOC values from iocs.json.
Exit codes:
0: no matches
1: one or more indicators matched
2: execution error
"""
import argparse
import fnmatch
import os
import sys
from pathlib import Path
OUT = Path(os.environ.get("OUT", "hp-atomic-arch-aur-compromise-ioc-scope"))
CONTENT_INDICATORS = [
"atomic-lockfile@1.4.2",
"atomic-lockfile@1.0.0",
"js-digest@1.0.0",
"6144d433f8a0316869877b5f834c801251bbb936e5f1577c5680878c7443c98b",
"42b59fdbe1b72895b2951412222ebf40",
"olrh4mibs62l6kkuvvjyc5lrercqg5tz543r4lsw3o6mh5qb7g7sneid.onion",
"temp.sh",
"https://temp.sh/deps",
"atomic-lockfile",
"1.4.2",
"1.0.0",
"js-digest"
]
PATH_INDICATORS = [
"/sys/fs/bpf/hidden_pids",
"/sys/fs/bpf/hidden_names",
"/sys/fs/bpf/hidden_inodes"
]
EXCLUDE_DIRS = {".git", "node_modules", "vendor", "dist", "build", ".venv", "__pycache__"}
def _iter_files(root):
root = Path(root)
if not root.exists():
return
if root.is_file():
yield root
return
for current, dirs, files in os.walk(root):
dirs[:] = [d for d in dirs if d not in EXCLUDE_DIRS]
for name in files:
yield Path(current) / name
def _path_matches(path):
text = str(path)
matches = []
for indicator in PATH_INDICATORS:
if not indicator:
continue
if indicator.startswith(("/", "~")):
candidate = Path(os.path.expanduser(indicator))
if candidate.exists() and path == candidate:
matches.append(indicator)
if indicator in text or fnmatch.fnmatch(text, indicator) or fnmatch.fnmatch(path.name, indicator):
matches.append(indicator)
return matches
def _content_matches(path):
try:
content = path.read_text(errors="ignore")
except Exception:
return []
return [indicator for indicator in CONTENT_INDICATORS if indicator and indicator in content]
def _scan_roots(roots):
matches = []
for root in roots:
if not root:
continue
for path in _iter_files(root):
for indicator in _path_matches(path):
matches.append(f"{path}: path matched {indicator!r}")
for indicator in _content_matches(path):
matches.append(f"{path}: content matched {indicator!r}")
return matches
def main():
parser = argparse.ArgumentParser(description="Scan files and logs for Halting Problems IOC values")
parser.add_argument("roots", nargs="*", default=["."], help="File or directory roots to scan")
parser.add_argument("--log-root", default=os.environ.get("LOG_ROOT", ""), help="Optional exported log directory")
args = parser.parse_args()
OUT.mkdir(parents=True, exist_ok=True)
indicator_lines = sorted(set(CONTENT_INDICATORS + PATH_INDICATORS))
(OUT / "ioc-indicators.txt").write_text("\n".join(indicator_lines) + "\n")
roots = list(args.roots)
if args.log_root:
roots.append(args.log_root)
matches = _scan_roots(roots)
if matches:
(OUT / "ioc-scope-matches.txt").write_text("\n".join(matches) + "\n")
print(f"[!] Found {len(matches)} IOC matches; details written under {OUT}")
return 1
print(f"[+] No IOC matches found; indicator inventory written under {OUT}")
return 0
if __name__ == "__main__":
try:
sys.exit(main())
except Exception as exc:
print(f"[-] Execution failure: {exc}", file=sys.stderr)
sys.exit(2)
Downstream Abuse Audits
Compromised workstations expose active API credentials, requiring immediate rotated revocation. The following platforms are at risk:
- GitHub OIDC and PATs: Attackers harvested SSH private keys and Git Personal Access Tokens. Auditors must inspect recent action runs and release logs during the exposure window.
- Cloud IAM Credentials: AWS, Azure, and GCP session tokens. CloudTrail and Activity Logs should be queried for AssumeRole or write operations originating from unexpected IP addresses.
- NPM and Package Registries: Publishing tokens and credentials. Registry profiles must be audited for unauthorized version publishes or token additions.
Remediation and Closure
- Preserve evidence: Capture the
/var/log/pacman.logtransaction histories and local directories under~/.npm/_cacache/and~/.bun/to verify package installation times and version identifiers. - Stop active execution: Isolate the affected host from the local network to terminate active Tor proxy tunnels and stop ongoing secret collection.
- Contain affected assets and identities: Revoke active IAM roles, GitHub Personal Access Tokens, and package registry tokens that had write or administrative permissions on this workstation.
- Revoke and rotate credentials: Rotate all browser-saved passwords, Slack/Discord sessions, and SSH credentials from a trusted environment.
- Eradicate malicious artifacts and persistence: Remove any systemd service units configured with
Restart=alwaysandRestartSec=30that point to the/usr/bin/depsbinary or other suspicious file paths. - Rebuild untrusted systems: Since the payload installs an eBPF rootkit capable of hiding processes, files, and network connections, a full operating system reinstallation from trusted media is required.
- Audit downstream activity: Inspect GitHub logs, AWS CloudTrail, and NPM registry logs for unauthorized activity during the June 9-12 window.
- Recover using verified artifacts: Redeploy clean build images and verify that AUR helper caches are completely empty.
- Close: Close the incident response ticket only when all exposed credentials are rotated and clean endpoint telemetry logs are confirmed.
Sources
- IFIN Discourse: 400 AUR Packages Compromised with Infostealer and Rootkit - Role: PRIMARY_RESEARCH - Claims Supported: Wave definitions, package listings.
- ioctl.fail: Preliminary Analysis of AUR Malware - Role: PRIMARY_RESEARCH - Claims Supported: Rust infostealer analysis, C2 onion address, eBPF rootkit mechanism.
- Arch Linux aur-general General Discussion List Archive - Role: DIRECT_SOURCE - Claims Supported: Discussion timelines, affected community package listings.
- lenucksi/aur-malware-check GitHub Repository - Role: COMMUNITY_DETECTION - Claims Supported: Detection helper commands and file paths.
- Socket.dev: atomic-lockfile npm package - Role: REGISTRY_METADATA - Claims Supported: npm package publication metadata.
- Chaos.social Mastodon Post by David Runge - Role: DIRECT_SOURCE - Claims Supported: Forgery of arojas 유지관리자 commit signature details.
IOC Clipboard
5 IOCsolrh4mibs62l6kkuvvjyc5lrercqg5tz543r4lsw3o6mh5qb7g7sneid.onion olrh4mibs62l6kkuvvjyc5lrercqg5tz543r4lsw3o6mh5qb7g7sneid[.]onion https://temp.sh/upload` hxxps://temp[.]sh/upload` 6144d433f8a0316869877b5f834c801251bbb936e5f1577c5680878c7443c98b 6144d433f8a0316869877b5f834c801251bbb936e5f1577c5680878c7443c98b 7883bda1ff15425f2dbe622c45a3ae105ddfa6175009bbf0b0cad9bf5c79b316 7883bda1ff15425f2dbe622c45a3ae105ddfa6175009bbf0b0cad9bf5c79b316 47893d9badc38c54b71321263ce8178c1abb10396e0aadf9793e61ec8829e204 47893d9badc38c54b71321263ce8178c1abb10396e0aadf9793e61ec8829e204