Severity Daily

IT and AI security incidents, checked against the primary source

Tag: SIP

  • Three SIPp buffer overflows are fixed on master and in no release; 3.7.7 is still the newest tag

    Three SIPp buffer overflows are fixed on master and in no release; 3.7.7 is still the newest tag

    VulnCheck published three buffer overflows in SIPp on Sunday; all three are fixed in the master branch, and none of them are in a release, because there has not been one since 3.7.7.

    What happened

    NVD published CVE-2026-90778, CVE-2026-90779 and CVE-2026-90780 on September 13, 2026, within 300 milliseconds of one another at 12:17 p.m. UTC. All three are assigned by VulnCheck, all three name SIPp — the open-source SIP traffic generator and test tool — and all three give the affected range as “through 3.7.7.” Each carries a CVSS v3.1 base score of 7.5 with the vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H and a secondary CVSS v4.0 score of 8.7, both assigned by VulnCheck. All three records were still at vulnStatus Received when this story was checked. The VulnCheck advisory for the first credits Tristan Madani.

    The three descriptions, verbatim:

    • CVE-2026-90778: “SIPp through 3.7.7 contains a buffer overflow vulnerability in get_peer_tag() function when processing SIP To headers with tag parameters of 2049 bytes or more.” CWE-120.
    • CVE-2026-90779: “SIPp through 3.7.7 contains a stack buffer overflow vulnerability in createAuthHeader() when processing SIP authentication challenges with oversized algorithm parameters.” CWE-121.
    • CVE-2026-90780: “SIPp through 3.7.7 contains a buffer overflow vulnerability in the get_header() function in src/sip_parser.cpp when processing SIP messages with header content exceeding 20,490 bytes.” CWE-120.

    The oddly specific byte counts come from one constant. include/sip_parser.hpp at tag v3.7.7 defines MAX_HEADER_LEN as 2049. get_peer_tag() writes into static char tag[MAX_HEADER_LEN], which is where 2,049 comes from. get_header() writes into static char last_header[MAX_HEADER_LEN * 10], which is where 20,490 comes from. The numbers in the CVE descriptions are the buffer sizes, and they line up exactly with the source at the tag.

    Reading that source at v3.7.7 shows three plain misses. get_peer_tag() copies the To-header tag one character at a time with tag[tag_i++] = *(ptr++) inside a loop whose only exit conditions are the end of the string and a set of delimiter characters; the index is never compared against the buffer. get_header() accumulates matched headers with dest += sprintf(dest, "%s", src), with no bound on dest. createAuthHeader() declares char algo[32] = "MD5", locates algorithm= in the challenge, measures the value with strcspn, and then calls strncpy(algo, start, end - start) — passing the length of the source rather than the size of the destination, which is the failure mode strncpy is most often reached for and least protects against.

    The fixes exist, and are not in a release

    Each NVD record references a commit and a pull request: ddf22d1 and PR #879 for the tag overflow, 1d4a562 and PR #880 for the auth header, 8ddfb43 and PR #881 for get_header(). Severity Daily read the same files on the master branch rather than relying on the commit references, and the repairs are there:

    • get_peer_tag() on master carries the same copy loop with one added condition: && tag_i < (int) sizeof(tag) - 1.
    • get_header() on master computes last_header_end from sizeof(last_header) and replaces every sprintf with a bounded snprintf against the remaining space, jumping to a truncation path when the return value will not fit.
    • createAuthHeader() on master deletes the stristr/strcspn/strncpy sequence entirely and calls getAuthParameter("algorithm", auth, algo, sizeof(algo)), which takes the destination size, falling back to MD5 when the parameter is absent.

    The remaining question is which release contains them, and the answer is none. Severity Daily probed the repository for tags after v3.7.7 by requesting a known source file at each candidate tag: v3.7.6 and v3.7.7 return the file, while v3.7.8, v3.7.9, v3.8.0 and v4.0.0 all return 404. v3.7.7 is the newest tag in the repository. Every published SIPp release is inside the affected range.

    The project’s own changelog does not help either. CHANGES.md at master and at v3.7.7 both stop at a heading reading “Features added in 3.7.5.” Neither 3.7.6 nor 3.7.7 has an entry, so a reader who upgrades has no document describing what changed, and no place where a security fix would be announced if one were made.

    Why it matters

    The scoring deserves reading carefully before anyone treats this as an emergency. The vector is availability-only — C:N/I:N/A:H. VulnCheck is describing crashes, not code execution. These are stack and static-buffer overflows in C++ string handling, which is the category from which exploitation sometimes follows, but no one has claimed it here and this site is not going to claim it either.

    What makes it worth attention is the direction the attack runs. SIPp is a test tool, and the instinct is to file test tools under “lab, not production, not exposed.” But the data SIPp parses does not come from its operator. It comes from the system under test, over the network, in responses to the traffic SIPp generated. The overflowing inputs here are a To-header tag, an authentication challenge, and header content — all of them fields the far end supplies. In client mode the attacker position is the device SIPp is pointed at. In server mode, which SIPp supports and which is how it is run as a responder in automated suites, the attacker position is anyone who can reach the port.

    That is the useful lesson, and it generalizes past SIPp. Test harnesses are written on the assumption that the operator controls both ends, so their parsers are built for well-formed input from a cooperating peer. When the peer is a piece of equipment being evaluated, or a soak-test target on a shared lab network, or a CI runner reachable from more of the network than anyone intended, the assumption stops holding — and the harness is usually running with fewer restrictions than the software it is testing, because nobody hardens the thing that is only used for testing.

    This is the second SIP tool in two days to arrive with a fix that exists only outside a release. sngrep CVE-2026-90558 ran here on Saturday on precisely that shape. The pattern in both cases is a small, long-lived, single-purpose C tool that many people install once and never update, maintained actively enough that fixes land in the branch but not actively enough that a release follows. For the operator the consequence is the same either way: the remedy on offer is not a version number.

    Distribution makes it worse here than it was for sngrep. Debian’s package tracker reports that sipp “is not part of any Debian distribution” and shows the last version as 3.1-11, removed from testing in 2007. There is no distribution security team positioned to backport these three commits into a package most SIPp users would receive. Whoever is running SIPp almost certainly built it from a tarball or a checkout, which means the upgrade path is a decision each operator makes alone.

    What to do

    There is no release to move to. The fixes are on master, and taking them means building from the branch rather than from v3.7.7.

    That is a real cost and worth stating plainly: master has diverged from 3.7.7 by more than these three commits. The authentication code in particular has been reworked, with the MD5-specific hashing types replaced by generic ones and the USE_SHA256 build guards removed. Building master is not equivalent to applying three patches, and anyone with a scenario suite that depends on current behavior should expect to re-test it.

    The narrower option is to cherry-pick ddf22d1, 1d4a562 and 8ddfb43 onto a v3.7.7 checkout. The first two are small and self-contained. The get_header() change is larger, because converting sprintf to bounded snprintf touched every write in the function and added a truncation path.

    Independent of either, treat SIPp the way you would treat any other network-facing parser. Do not leave a server-mode instance listening past the run that needed it, do not point SIPp at equipment you do not control from a host that matters, and do not assume a crashed test harness in a long soak run is a flaky tool rather than a signal.

    Sourcing note

    Checked: the NVD records for CVE-2026-90778, CVE-2026-90779 and CVE-2026-90780, read from the NVD REST API, for descriptions, scores, vectors, CWEs, affected ranges, timestamps and status. The VulnCheck advisory for CVE-2026-90778 for the researcher credit. SIPp source at tag v3.7.7 and at master, retrieved as raw files, for the vulnerable code, the MAX_HEADER_LEN constant and each repair. The presence and absence of release tags, established by requesting a known file at each candidate tag. CHANGES.md at both refs. Debian’s package tracker for packaging status.

    Not reached: the GitHub API is unavailable from this environment, so pull requests #879, #880 and #881 were not read directly and their merge status was not confirmed from GitHub. The fixes were verified by reading the code on master instead, which establishes that the repairs are in the branch regardless of how they arrived. The release date of v3.7.7 was not established; the project publishes no changelog entry for it. VulnCheck advisory pages for CVE-2026-90779 and CVE-2026-90780 were not individually read.

    Unresolved: no SIPp maintainer statement on these three records was found, and the project has issued no advisory. Whether a release carrying the fixes is planned is unknown. No exploitation has been reported by anyone, and none is claimed here. cisa.gov returns 403 to automated retrieval and was not consulted; none of the three records carries CISA fields in NVD, and no federal deadline attaches to them.

  • sngrep’s 9.8 stack overflow is fixed in master and in no release, and Debian’s newest package is the top of the affected range

    sngrep’s 9.8 stack overflow is fixed in master and in no release, and Debian’s newest package is the top of the affected range

    A stack buffer overflow reachable from any SIP packet sngrep renders carries a 9.8, the patch exists as a commit on master, and no tagged release or distribution package contains it.

    What happened

    On September 12, 2026, at 6:16 p.m. UTC, VulnCheck published CVE-2026-90558 against sngrep, the terminal SIP packet viewer maintained by Irontec and used by most people who debug voice infrastructure for a living. The record carries a CVSS v3.1 base score of 9.8 with the vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H, a CVSS v4.0 score of 9.3, and CWE-121, stack-based buffer overflow. Both scores come from [email protected]. There is no score from the project.

    The description reads: “sngrep through 1.8.4 contains stack buffer overflow vulnerabilities in SIP attribute formatting routines when header values exceed the 255-byte buffer limit. Attackers can craft malicious SIP packets with oversized Call-ID, X-Call-ID, or other header fields to overflow stack buffers and cause crashes or execute arbitrary code during packet parsing and rendering.” VulnCheck’s advisory credits Tristan Madani.

    The affected range in the NVD record runs from version 0 through 1.8.4. There is no versionEndExcluding, no fixed version named anywhere in the record, and no release tag in the reference list — there is a commit.

    That commit is 1ff74ee3ab5ff280e8ba976aa8c744dca57eb35b, authored by the project’s maintainer, Ivan Alonso. Its message is unusually precise about reachability, and worth reproducing: “call_get_attribute() formatted the Call-ID, X-Call-ID and Reason header text with an unbounded sprintf(“%s”). Call-ID/X-Call-ID can hold up to MAX_CALLID_SIZE/MAX_XCALLID_SIZE (1023 bytes) and Reason text is copied from the raw payload (up to MAX_SIP_PAYLOAD), while all callers pass a 255-byte SIP_ATTR_MAXLEN stack buffer (call list rendering, sort compare). A SIP message with a long Call-ID, X-Call-ID or Reason header overflowed the stack, triggerable via pcap, live capture or HEP/EEP remote capture.”

    The change is seven added and seven removed lines across src/sip_call.c and src/sip_msg.c. We read both files at the v1.8.4 tag and at master. At 1.8.4, src/sip_call.c writes the Call-ID with sprintf(value, "%s", call->callid), and the X-Call-ID and Reason text the same way. On master, those three lines read sprintf(value, "%.*s", SIP_ATTR_MAXLEN - 1, ...). src/sip_attr.h defines SIP_ATTR_MAXLEN as 255; src/sip.h defines MAX_CALLID_SIZE and MAX_XCALLID_SIZE as 1024 and MAX_SIP_PAYLOAD as 10240.

    The second half of the commit is a separate defect. At 1.8.4, src/sip_msg.c already used the bounded form, but passed SIP_ATTR_MAXLEN as the precision rather than SIP_ATTR_MAXLEN - 1 — 255 characters plus a terminator into a 255-byte buffer. Master corrects that on four calls. The code that looked guarded was off by one byte; the code that looked unguarded was off by up to 768.

    Now the part that decides what a reader can do. configure.ac on master still reads AC_INIT([sngrep], [1.8.4], ...) — not bumped since the fix landed — and the ChangeLog has no entry after “2026-07-24 Ivan Alonso — sngrep 1.8.4 released.” There is no 1.8.5.

    Debian carries 1.8.2-1 in stable and 1.8.4-1 in testing and unstable, the latter accepted into unstable on July 30, 2026, and migrated to testing on August 4, 2026. Every one of those is inside the affected range, because the range starts at zero. The newest sngrep any mainstream distribution ships is the ceiling of the range, not above it.

    sngrep is not in CISA’s Known Exploited Vulnerabilities catalog, whose current published version is 2026.09.11, and no exploitation has been reported. The NVD record carries no cisaExploitAdd or cisaActionDue field.

    Why it matters

    The 1.8.4 release is the ceiling of this affected range, and 1.8.4’s own changelog contains the line “sip: fix stack buffer overflow on non-numeric Warning header.” Seven weeks ago the project fixed a stack buffer overflow in SIP header handling. The release that shipped that fix is the top of the affected range for a second stack buffer overflow in SIP header handling, in adjacent functions, found by looking at the same class of formatting call. That is not a criticism of the maintainer, who fixed this one quickly and documented it better than most vendors document anything. It is an observation about how these audits go: when one sprintf in a family gets bounded, someone eventually reads the rest of the family.

    What makes the 9.8 defensible is where the input comes from. sngrep is not a service, so the instinct is to file this under “local tool, low priority.” The commit message names three paths, and two of them do not require the operator to do anything unusual. Live capture is the ordinary way sngrep is used: an engineer runs it on a session border controller or a PBX and watches signaling go by. Anyone who can put a SIP message on a monitored interface — for a public-facing SIP service, anyone on the internet — supplies the Call-ID. The overflow then happens during call list rendering and during sort comparison, meaning it fires as the operator looks at the screen, not as a result of any decision the operator makes about the packet.

    The third path is the one to check tonight. sngrep can act as an EEP/HEP capture server, receiving signaling from remote agents. In src/setting.c, eep.listen defaults to off — but when it is turned on, eep.listen.address defaults to 0.0.0.0, eep.listen.port to 9060, and eep.listen.pass to the empty string. A shop that enabled remote capture during a troubleshooting session and left it on has a UDP listener on every interface, with no password unless someone set one, feeding attacker-controlled header text straight into the formatting routines this CVE describes.

    Then there is the privilege question the CVSS vector does not capture. Packet capture needs elevated rights, and the path of least resistance is sudo sngrep. A stack overflow in a root process on the same host as the telephony stack it is debugging is a different outcome than the same overflow in an unprivileged viewer. The score asserts C:H/I:H/A:H on the assumption that code execution is achievable; whether it is, on a toolchain with stack protector and FORTIFY_SOURCE, VulnCheck does not demonstrate and we will not assert. What is certain is the crash, and it happens in the tool you were using to find out what was wrong.

    The shape of this record is one this publication has now seen four times in four days: a real fix exists in version control, the CVE’s affected range ends at the last release because there is nothing later to point at, and every scanner that resolves version numbers against that range will keep reporting the newest available build as vulnerable, correctly. HAProxy’s HTTP/3 smuggling fix, covered here this morning, has the same structure. The difference is that HAProxy ships releases on a schedule measured in weeks. sngrep’s last two releases were eleven months apart. “Wait for the next release” is not a remediation timeline here; it is a hope.

    What to do

    There is no version to upgrade to. The options are to build from master, which contains commit 1ff74ee3ab5ff280e8ba976aa8c744dca57eb35b, or to apply that seven-line change to whatever source your distribution packages. Both touched functions, call_get_attribute() in src/sip_call.c and msg_get_attribute() in src/sip_msg.c, are small and the change is mechanical: bound the writes with %.*s and SIP_ATTR_MAXLEN - 1.

    Until then, check eep.listen in your sngrep configuration, which lives in ~/.sngreprc or /etc/sngreprc. If it is on and you are not actively using remote capture, turn it off. If you are, set eep.listen.pass to something, and bind eep.listen.address to a management interface rather than 0.0.0.0.

    Treat pcap files from outside your organization as untrusted input; sngrep begins rendering the call list as soon as it opens one. A capture emailed by a carrier or a customer to help diagnose a problem is exactly the delivery vehicle this flaw wants.

    Stop running sngrep as root where you can. Granting CAP_NET_RAW and CAP_NET_ADMIN to the binary, or capturing to a file with a minimal tool and viewing it as an unprivileged user, removes the worst version of this outcome without waiting for anyone.

    Finally, if a scanner reports sngrep 1.8.4 as vulnerable and someone is about to mark it a false positive because 1.8.4 is the latest release: it is not one. That is the correct answer to the question the scanner was asked.

    Sourcing note

    Checked: the NVD record for CVE-2026-90558, which supplied the description, both CVSS vectors and their source, CWE-121, the affected range, and the reference list; VulnCheck’s advisory, which supplied the researcher credit; the sngrep repository’s shipped source at the v1.8.4 tag and at master, read directly via raw.githubusercontent.com, which is how the sprintf calls before and after, the value of SIP_ATTR_MAXLEN, the eep.listen defaults in src/setting.c, the unchanged version string in configure.ac, and the ChangeLog entries were confirmed rather than taken on description; and the Debian package tracker for the packaged versions. The KEV catalog was read from the cisagov/kev-data mirror on GitHub, because cisa.gov returns 403 to automated fetching; the catalog version read was 2026.09.11 and sngrep does not appear in it.

    Could not reach: GitHub’s commit-listing and tag pages, which are disallowed to automated fetching by robots.txt, so the calendar date the fix commit landed is not established here — only that it is present on master and absent from v1.8.4.

    Unresolved: whether the overflow is exploitable beyond a crash on a distribution build with stack protector and FORTIFY_SOURCE enabled. VulnCheck’s 9.8 asserts confidentiality, integrity, and availability impact; the advisory does not show code execution, and the project has published no advisory of its own. Also unresolved: whether a 1.8.5 release is planned.