This Week In Security: Git Deep Dive, Mailchimp, And SPF

First up, git has been audited. This was an effort sponsored by the Open Source Technology Improvement Fund (OSTIF), a non-profit working to improve the security of Open Source projects. The audit itself was done by researchers from X41 and GitLab, and two critical vulnerabilities were found, both caused by the same bad coding habit — using an int to hold buffer lengths.

On modern systems, a size_t is always unsigned, and the same bit length as the architecture bit-width. This is the proper data type for string and buffer lengths, as it is guaranteed not to overflow when handling lengths up to the maximum addressable memory on the system. On the other hand, an int is usually four bytes long and signed, with a maximum value of 2^31-1, or 2147483647 — about 2 GB. A big buffer, but not an unheard amount of data. Throw something that large at git, and it will break in unexpected ways.

Our first example is CVE-2022-23521, an out of bounds write caused by an int overflowing to negative. A .gitattributes file can be committed to a repository with a modified git client, and then checking out that repository will cause the num_attrs variable to overflow. Push the overflow all the way around to a small negative number, and git will then vastly under-allocate the attributes buffer, and write all that data past the end of the allocated buffer.

CVE-2022-41903 is another signed integer overflow, this time when a pretty print format gets abused to do something unexpected. Take a look at this block of code:

int sb_len = sb->len, offset = 0;
if (c->flush_type == flush_left)
offset = padding - len;
else if (c->flush_type == flush_both)
offset = (padding - len) / 2;
/*
* we calculate padding in columns, now
* convert it back to chars
*/
padding = padding - len + local_sb.len;
strbuf_addchars(sb, ' ', padding);
memcpy(sb->buf + sb_len + offset, local_sb.buf,
local_sb.len);

The exploit format would look something like %>(2147483647)%a%>(2147483646)%x41, where the code above runs for every padding instance (The %>(#) blocks) found in the format. The first time through this code adds (2^31)-1 spaces to the front of the output string. That number just happens to be the max value of a four byte signed integer. But the code block above gets run another time, and once more text is added to the buffer, pushing its length over the max integer value. The first line of that block does an implicit cast from size_t to int, setting sb_len to a negative value.

Then in the memcpy() call, sb->buf is a pointer to the start of the buffer, sb_len is our overflowed large negative number, and offset will be a user-controlled value. This means the location of the destination sent to memcpy() can unintentionally be set to a lower memory location than the start of the intended buffer. Attacker controlled writes. I’ve added some debugging printf() statements to this text block, and run a test-case:

$ ./bin-wrappers/git log -1 --pretty="format:%>(2147483647)%a% >(2147483635)%s" > /dev/null
Padding: 2147483647
sb_len: 0
offset: 2147483647
Memcpy:
Padding: 2147483635
sb_len: -2147483647
offset: 2147483591
Memcpy: CI: upgrade to macos-12, and pin OSX version
=================================================================
==844038==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7fd8989f97c8 at pc 0x7fdb15e49d21 bp 0x7ffe8fa5c100 sp 0x7ffe8fa5b8b0
WRITE of size 44 at 0x7fd8989f97c8 thread T0
0x7fd8989f97c8 is located 56 bytes to the left of 4831838268-byte region [0x7fd8989f9800,0x7fd9b89f983c)

The first quartet of outputs there is the setup, priming the log line with padding to be max int long. The second quartet is the buffer overrun, where sb_len is set to negative, and then added to the offset to give us a location 56 bytes to the left of the start of the buffer. The content that gets printed to that location is in this case %s, which gets replaced by the subject line of the commit — 44 bytes long. The authors suggest that this could be weaponized against a “git forge”, AKA GitHub and GitLab, as those software suites run the git archive command, which can invoke a user-controlled pretty string.

Fixes were pushed to the git source code back on December 8th, but new releases containing those fixes are just now available. There are approximately 2200 instances of the raw int issue, and those will take a while to clean up, even with some fun hacks like cast_size_t_to_int(), an inline function that just kills the program if a 2 GB+ size_t is handled. So go update!

Mailchimp — Again

It seems the folks at Mailchimp can’t catch a break, as their internal administration tools were accessed once again by attackers, leading to the exposure of 133 customer accounts, including WooCommerce. This is the third time Mailchimp has fallen to a social engineering or phishing attack in the last year, and each time has resulted in spear-phishing emails sent to end users. So if you’re on any Mailchimp mailing lists, keep this breach in mind next time a related email arrives. (Editor’s note: Hackaday’s two newsletters use Mailchimp, and we were not notified, so we believe that we’re good.)

Royal Mail Ransomware

In a story that could have some big consequences, the UK’s Royal Mail has suffered a ransomware attack on their system for handling international mail. The attack uses Lockbit ransomware, a group suspected to be a Russian-speaking ransomware gang. This could be significant, as an attack on an actual government agency is way more serious than an attack on a business. Since Lockbit runs as ransomware-as-a-service, it’s going to be very difficult to determine exactly who actually pulled off the attack. For now, the recommendation is simple: don’t send any international mail. Oof.

Edit: A patient reader has pointed out that the Royal mail has been privatized since 1969. So while the ransomware affects a critical service, it’s not a government agency.

Scanning SPF Records

[Sebastian Salla] has what may be considered a strange hobby, in the form of scanning SPF records for odd misconfigurations. In his latest adventure, that scan was the top 3 million most visited domains. And misconfiguration was found.

But hang on, what’s an SPF and why do we care? Sender Policy Framework is a txt record that is part of a domain’s DNS records. And it specifies what IP addresses are actually authorized to send email for that domain. So if an incoming email claims to be from a domain with a valid SPF record, and the sending IP address is not on that record, it’s pretty clearly not really from the claimed domain.

And having your domain’s emails get rejected because of an SPF problem is one of the surest ways to catch flak. So it’s tempting to make the SPF record a bit more … *liberal* than perhaps it should be. And the most extreme iteration of this is to just slap a +all on your SPF record and be done with it. Sure, it tells the world that every spammer anywhere that uses your domain is actually sending real emails, but at least it gets the boss’s outgoing emails working again. With over a thousand domains set to SPF +all, apparently that’s more common a fault than anticipated.

The really interesting bit is the who’s who of those misconfigured domains, like multiple US governmental agencies, other governmental domains around the world, and multiple universities. The most interesting one was the Ukrainian ministry of defense, where the SPF record was clipped from a -all to +all about 4 months ago.

Bits and Bytes

Tailscale discovered a potentially serious issue, where knowing the node ID of another client would allow an attacker to add the node to their own tailnet. This would have put an attacker on the inside of your VPN, definitely a bad scenario. But before you get your pitchforks, the vulnerable code was deployed for less than four months before it was fixed. It was privately reported on the 11th of this month, and fixed on the 12th. And to boot, the attack leaves a log signature that the Tailscale was able to scan for, and concluded that it was isolated to the proof-of-concept testing. You can check your own dashboard for any nodes shared out of their own tailnet for confirmation. And while it’s a nasty vulnerability, good for Tailscale for disclosing it. Many vendors would have sat on this one and never made it public.

The Linux kernel had a buffer overflow in its Netfilter code, where a buffer overflow could result in both data leakage and code execution. There isn’t a path to remote exploitation, but the email linked above contains a full PoC for a local privilege escalation. And if Kernel exploitation is your thing, Google’s Project Zero has a new write-up on the subject, all about null dereferencing.

And if you use ManageEngine from Zoho, then today your hair may be on fire, if you haven’t updated to the release that fixes CVE-2022-47966. Researchers at Horizon3 have reverse-engineered the patch, and spilled the beans on this RCE. It’s an issue in how SAML single-sign-on is implemented, owing in part to an extremely old library packaged as part of the product. It’s a pretty easy exploit to pull off, so time to go double check those installs!

10 thoughts on “This Week In Security: Git Deep Dive, Mailchimp, And SPF

  1. “This could be significant, as an attack on an actual government agency is way more serious than an attack on a business.”

    Has Royal Mail been re-nationalised on the quiet? Been a while since it was a government department….

      1. Well Royal Mail was in UK Gov hands much more recently than UK Gov was under Royal control. State and crown are quite separate these days, other than for ceremonial duties.

      2. Welcome to the weird world of privatisation in the Uk! It’s not part of the government, but is considered critical infrastructure so your comment is correct in spirit if not technically accurate.

  2. Linux netfilter overflow is in Linux kernel 6.2.0-rc1. This is an _early_ testing release candidate, not a released kernel. Unless you are intentionally testing pre-release kernels, this issue does not affect you.

  3. The code samples (those with the left-right scroll bar) need the “-&gt” converted to the correct “->” that is used in that code, which I’d been looking at for other reasons (adding hard truncation, without ellipsis).

Leave a Reply to DanCancel reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.