Hanwha Vision 保安攝影機韌體內藏可管理數百個 GitHub 儲存庫的 token
One grep, full repo access
Hanwha Vision 的保安攝影機韌體內藏一個可管理其 GitHub 組織數百個儲存庫的 token,研究人員解密韌體後發現該憑證。研究人員檢查約 600 款攝影機中可取得的約 500 份韌體,以同一方法解密其中 62%;3 份韌體含有同一 token,問題源於 Vite 建置時把整個 process.env 打包進攝影機介面。
A GitHub token with admin rights to hundreds of repositories in Hanwha Vision's organization shipped inside the firmware for its security cameras, duplicated across roughly 30 files in a single image.
Hanwha Vision, the surveillance maker that began as Samsung Techwin, publishes firmware blobs for each camera model on its website. A researcher pulled one down and ran it through binwalk expecting a rootfs. Inside was a tarball holding some AI components and an fwimage.tgz that binwalk flagged as encrypted.
The outer layer was already documented. Matt Brown's writeup on these cameras covers the passphrase: HTW followed by the model number. For the XNP-9300RW that is HTWXNP-9300RW, and it decrypts the archive.
Inside sat a second fwimage.tgz on a different encryption scheme. The outer tarball also carried an fwupgrader binary, so the researcher put Claude Code on it and came back to a working rootfs. Hanwha had obfuscated how fwupgrader decrypts the real image. The AES key is XOR'd against a small static key table in the binary and reassembled at runtime; the IV is stored as plaintext. The binary does the decryption by shelling out to the openssl CLI, and even the command fragments are XOR-obfuscated the same way.
Reconstructed, the call is:
openssl enc -md sha256 -aes-256-cbc -d \
-K <KEY> -iv <IV> -in <INPUT> -out <OUTPUT>
The key and IV are hardcoded and identical across the model line:
KEY = dfa049bb922e63e2decc764af5628068e5b7a2662e479a615b14643e567579b0
IV = 53f926801b81454a4f889c9a390db6e6
Burning a key into the hardware would at least force an attacker to own a camera before decrypting anything. A static key reused across the whole product line means one extraction opens every image.
With the rootfs mounted, trufflehog surfaced the token. It held admin privileges across hundreds of repositories in Hanwha's GitHub org. It shows up in ~30 files because of a build mistake: the camera UI is built with vite, and one variable is assigned the entirety of process.env at build time. The whole CI environment ends up baked into the bundle. Alongside GITHUB_NPM_TOKEN (value prefixed ghp_) were ordinary build vars like npm_command and npm_config_userconfig.
Because the leak lives in the shipped UI bundle, the researcher's read is that anyone who reached a camera's admin interface likely received the token over the wire, though it may only have sat on disk without ever being served.
The same process.env dump carried three internal addresses in IP space assigned to the US Department of Defense:
SWARM_MASTER_NFS_ADDRESS: 55.101.212.23OTEL_ELASTIC_URL: http://55.101.212.21:5601/CIMIP: 55.101.211.213
Hanwha later confirmed it did not know the range was DoD-allocated. In its reply it said it had used the addressing internally since its predecessor Samsung Techwin and is now planning to change its network structure. Using live, routable third-party space for internal addressing is a bad habit on its own, independent of whose space it is.
To check the token was not a fluke, the researcher scraped Hanwha's site for every firmware available, around 500 of roughly 600 listed cameras, and decrypted 62% of them with the same method. Three contained GitHub tokens, all the same token.
The disclosure went to Hanwha's published security contact. They revoked the token and replied within 12 hours. The DoD correction came back the same way, promptly and directly.
If you build firmware or ship a web bundle out of CI, the fixes are specific. Never assign a bundler variable the full process.env; expose an explicit allowlist of the variables the client actually needs, and keep secrets off that list. And treat a decryption key that is static across a product line as obfuscation only, because opening one image opens all of them.
來源:DEV Community · dev.to