Ingram takes a file of addresses and checks them for nothing but authorization
网络摄像头漏洞扫描工具 | Webcam vulnerability scanning tool
At a glance
- What is it?
- Ingram is a Python scanning framework for network cameras with built in support for Hikvision, Dahua, Uniview and D-Link. It reads a target file, scans with a default concurrency of 300, writes recovered usernames and passwords into a plain CSV, and offers no allowlist, no dry run and no per target confirmation.
- Who is it for?
- Ingram belongs on an isolated network segment you own, with a target file you wrote yourself, and nowhere else. Read the scope section of this article before the install instructions: there is no authorization check, no dry run and no allowlist, the target file accepts CIDR and dashed ranges, and the project roadmap lists both distributed scanning and interactive region selection, which are scope-widening features rather than conveniences.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 48 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 5, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A target file is the entire input surface
Ingram takes one file and one output directory. The file holds one target per line, and the format section shows the four shapes it accepts: a bare address, an address with a port such as `192.168.0.2:80`, a CIDR range such as `192.168.0.0/16`, and a dashed range such as `192.168.0.0-192.168.255.255`. Lines beginning with a hash are comments.
If a line carries a port, that port is the one scanned for that target. Otherwise the scanner falls back to a built in list of common ports, which the README points at as living in `Ingram/config.py`, and other ports can be passed on the command line with `-p`.
The run itself is one script:
python run_ingram.py -i targets.txt -o outTwo more flags shape the pace. `-t` sets the number of concurrent processes, and the README names 300 as the default to be tuned to the machine and the network. `-T` sets the request timeout, and `-D` disables snapshot capture.
That is the whole interface. There is no configuration file, no policy object and no state beyond the output directory.
No allowlist, no dry run, no confirmation
This is the part to read twice before anything else.
Nothing in the tool asks whether you are allowed to scan what you asked it to scan. There is no allowlist of your own network, no dry run mode that resolves targets without sending anything, and no interactive confirmation. The target file format is the only gate, and it accepts ranges rather than only single hosts, so `192.168.0.0/16` is a valid input exactly as a single address is.
The documentation actively encourages widening. A section on using a port scanner recommends narrowing the input first, and its worked example uses masscan at a rate of 8000 packets per second across a port list, then feeds the survivors to Ingram. That is good practice for a large owned network and a fast way to sweep a large unowned one.
The roadmap makes the direction of travel explicit. Two planned items are interactive GeoIP based selection of which geographic region to scan, and distributed scanning. Neither is needed to find cameras on a lab network, and both make the blast radius of a mistyped range larger.
The disclaimer at the foot of the README says the tool is for security testing only, that illegal use is forbidden, and that the team is not responsible for the consequences. That is the only boundary in the design.
results.csv keeps recovered usernames and passwords in plain text
The output directory is four things.
.
├── not_vulnerable.csv
├── results.csv
├── snapshots
└── log.txt`results.csv` holds the complete findings, and the README gives the column order as ip, port, device type, username, password, vulnerability entry. So a successful run leaves recovered credentials sitting in a comma separated file in whatever directory you named with `-o`, with no encryption and no access control applied by the tool.
`not_vulnerable.csv` holds the devices that exposed nothing, which is the more useful file for triage, since it tells you what answered on the port you scanned and had nothing to report. `log.txt` is the run log. `snapshots` holds images captured from some of the devices, and that directory disappears if you pass `-D`.
Treat the output directory as a secret store rather than as a report. Anyone who can read `results.csv` has the credentials for every camera that answered, and anyone who can read `snapshots` has pictures of them.
Interruption recovery means running the same command again
The README claims support for resuming after an interruption and then qualifies it in the same sentence. Progress is not written in real time; it is recorded at intervals, so the recorded state cannot accurately reflect where the last run stopped.
The practical advice that follows is to repeat the previous command to continue. In other words there is no resume flag and no checkpoint file, and what you get is a scan that starts again and benefits only from whatever the interval snapshots let the tool skip.
That matters for the concurrency default. With 300 concurrent processes and no accurate checkpoint, a long sweep interrupted by a network blip costs you the whole sweep, which is part of why the masscan pre-filter step is recommended: fewer targets reach the slow part.
The full argument list in the README confirms there is no resume option. It is `-h` for help, `-i` for the input file, `-o` for the output directory, `-p` for ports, `-t` for the process count, `-T` for the request timeout, `-D` to disable snapshots and `--debug`.
requirements.txt pins nothing, and 3.11 is discouraged
The dependency file lists thirteen packages with no version constraints at all: colorama, gevent, IPy, loguru, lxml, ndjson, pwn, pwntools, pycryptodome, pyOpenSSL, requests and tzlocal, plus one more name in the same style. Nothing is pinned, so two people running the install on different days can end up with different behaviour and no way to tell from the repository.
Two entries deserve a second look. `pwn` and `pwntools` are both listed, and pwntools is the actively maintained name, so installing both puts two distributions of the same tool in one environment.
The Python requirement is stated in the install section rather than enforced anywhere: use Linux or a Mac, install Python 3.8 or newer, and try not to use 3.11 because compatibility with many of the packages is not good. That is an unpinned dependency set next to a specific minor version to avoid, which is the combination that produces a scanner that works on one machine and not on another.
The install itself is a clone, a virtual environment and one pip command, with the environment reactivated before every run.
Two features are struck through: alerts and live preview
Two capabilities have been removed, and both are still visible in the file with strikethrough headings.
The first was a WeChat notification at the end of a long scan. It used a third party push service, and the credentials were not configuration: the README told you to write your UID and APP_TOKEN into `run_ingram.py` itself through a config setter, which puts a shared secret in a tracked source file. That is now marked as removed, and nothing replaces it.
The second was live preview. You could log in through a browser to view devices as they were found, and a helper script under `show/show_rtsp/show_all.py` was provided for batch viewing, with the note that it still had problems. That heading is also struck through, and the repository root no longer contains a `show/` directory, so the removal is real rather than only a documentation change.
What replaced them is not stated. A scan now finishes silently apart from `log.txt`, which is the right default for a tool that walks a network.
One release in 2023, two scripts at the root, no tests
The repository has eight top level entries: `.gitignore`, the `Ingram/` package, `LICENSE`, `README.en.md`, `README.md`, `requirements.txt`, `run_ingram.py` and `targetMaker.py`.
Two things stand out. `targetMaker.py` sits at the root and is never explained in the documentation, even though making the target file is the first thing a user has to do by hand. And there is no test directory and no workflow directory, so a scanner with thirteen unpinned dependencies has neither an automated suite nor a documented continuous integration run in the tree.
The documentation is bilingual. `README.md` is the Chinese version and `README.en.md` is the English one, which is the version this article draws on, so any mismatch between the two files shows up here first.
Release history is thin: one tag, v2.0.0, published on 2023-08-08. The last push was on 2026-08-19, so the tagged release is three years behind the branch. The license is GPL-3.0 and the default branch is master. The code this project builds on is credited by name in the acknowledgements, including the Hikvision and Dahua work that the device support is derived from.
Editorial conclusion
Ingram belongs on an isolated network segment you own, with a target file you wrote yourself, and nowhere else. Read the scope section of this article before the install instructions: there is no authorization check, no dry run and no allowlist, the target file accepts CIDR and dashed ranges, and the project roadmap lists both distributed scanning and interactive region selection, which are scope-widening features rather than conveniences. Before a first run, pin your own requirements file, because requirements.txt pins nothing and the README warns against Python 3.11. And treat the output directory as a credential store, since results.csv holds usernames and passwords in plain text and snapshots holds images of the devices.
Frequently asked questions
What does Ingram scan?
Ingram is a Python scanning framework aimed at network cameras, with support built in for Hikvision, Dahua, Uniview and D-Link devices. It reads a file of target addresses, checks the ports you give it, and writes what it finds to CSV files plus device snapshots.
How do I run Ingram against a target file?
Create a file with one target per line, which may be a bare address, an address with a port, a CIDR range or a dashed range, with hash lines treated as comments. Then run python run_ingram.py -i targets.txt -o out. Ports default to the common ones defined in Ingram/config.py, -p overrides them, and -t sets concurrency, which defaults to 300.
What does results.csv contain in Ingram?
The complete findings, in the column order ip, port, device type, username, password, vulnerability entry, which means recovered credentials sit in plain text. not_vulnerable.csv lists devices that exposed nothing, snapshots holds images from some devices, and log.txt is the run log.
What scope controls does Ingram offer?
None beyond the target file itself. There is no allowlist of your own network, no dry run and no per target confirmation, and the file format accepts CIDR and dashed ranges. The README's disclaimer says the tool is for security testing only and that the team is not responsible for misuse.
Which Python version does Ingram need?
The install section asks for Python 3.8 or newer on Linux or a Mac, and advises against 3.11 because compatibility with many of the required packages is not good. requirements.txt lists its dependencies with no version constraints, so nothing enforces that choice for you.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/jorhelp-ingram)