RL Blog

Topics

All Blog PostsAppSec & Supply Chain SecurityDev & DevSecOpsProducts & TechnologySecurity OperationsThreat Research

Follow us

XX / TwitterLinkedInLinkedInFacebookFacebookInstagramInstagramYouTubeYouTubeblueskyBluesky

Subscribe

Get the best of RL Blog delivered to your in-box weekly. Stay up to date on key trends, analysis and best practices across threat intelligence and software supply chain security.

ReversingLabs: The More Powerful, Cost-Effective Alternative to VirusTotalSee Why
Skip to main content
Contact UsSupportLoginBlogCommunity
reversinglabsReversingLabs: Home
Solutions
Secure Software OnboardingSecure Build & ReleaseProtect Virtual MachinesIntegrate Safe Open SourceGo Beyond the SBOM
Increase Email Threat ResilienceDetect Malware in File Shares & StorageAdvanced Malware Analysis SuiteICAP Enabled Solutions
Scalable File AnalysisHigh-Fidelity Threat IntelligenceCurated Ransomware FeedAutomate Malware Analysis Workflows
Products & Technology
Spectra Assure®Software Supply Chain SecuritySpectra DetectHigh-Speed, High-Volume, Large File AnalysisSpectra AnalyzeIn-Depth Malware Analysis & Hunting for the SOCSpectra IntelligenceAuthoritative Reputation Data & Intelligence
Spectra CoreIntegrations
Industry
Energy & UtilitiesFinanceHealthcareHigh TechPublic Sector
Partners
Become a PartnerValue-Added PartnersTechnology PartnersMarketplacesOEM Partners
Alliances
Resources
BlogContent LibraryCybersecurity GlossaryConversingLabs PodcastEvents & WebinarsLearning with ReversingLabsWeekly Insights Newsletter
Customer StoriesDemo VideosDocumentationOpenSource YARA Rules
Company
About UsLeadershipCareersSeries B Investment
EventsRL at RSAC
Press ReleasesIn the News
Pricing
Software Supply Chain SecurityMalware Analysis and Threat Hunting
Request a demo
Menu
Threat ResearchOctober 30, 2019

Breaking the Linux Authenticode security model

Blog 9 in series: Digital Certificates - Models for Trust and Targets for Misuse

Tomislav Pericin headshot
Tomislav Peričin, Chief Software Architect & Co-Founder at ReversingLabsTomislav Peričin
FacebookFacebookXX / TwitterLinkedInLinkedInblueskyBlueskyEmail Us
Breaking the Linux Authenticode security model

Authenticode is a Microsoft code signing technology designed to guarantee the origin and integrity of an application. The core principle of its integrity verification system is code immutability. In other words, once an application is signed, its code cannot change without breaking the envelope integrity. This way, the user is guaranteed that the only code they are executing is the one created by the software publisher that signed it.

Portable executable is probably the most prolific application format used for code distribution. It can be found on a wide variety of hardware and software platforms. That’s why it is no wonder that many systems, other than its native Windows, end up supporting it in one way or another. On Linux, and its various distributions, it can be found both in the firmware and the user mode layer. As UEFI drivers for former, and as .NET Mono applications for latter.

Regardless of how the format got onto the platform, it is usually accompanied by its digital signing system, Authenticode, whose entire parsing and integrity validation procedures need to be completely reimplemented for portability. A daunting task by itself --- only amplified by the lack of proper documentation.

Both Authenticode and the executable format it is signing are extremely complex in their design. Mistakes and oversights in their parsing are, therefore, very common. And it is no wonder that certain edge cases even get mishandled the exact same way across different projects. Breaking the Authenticode security model is a cautionary tale of handling malformations.

A typical portable executable file consists of headers followed by an arbitrary number of sections and extra data appended after them. This extra appended data is called an overlay, and it is not a part of the image once the file is loaded in memory. Overlay is where the Authenticode signature resides when the executable image is signed. And it’s usually the last entry within a structured portable executable file.

Authenticode integrity validation is, therefore, a function of hashing the content which precedes the signature. Only two very small regions are excluded from this check. Checksum of the portable executable (a four-byte region), and the information about the Authenticode signature (an eight-byte structure containing its location and size). Neither of those regions have anything to do with the application code.

But what if they did? If it was possible to misappropriate one of those regions, it would be possible to change the code of the application after it is signed.

Authenticode signature location is perfect for such misuse. Its eight byte region describes the physical location of the signature within the file. The first four bytes define its offset, and the last four its size. This same combination of the fields can be found within the section header entry, where they describe the physical location of the section within the file. But, within the section header, these fields are in the inverse order. Here’s how these two structures look like side by side.

typedef struct _IMAGE_SECTION_HEADER {
                BYTE Name[8];
                union {
                DWORD PhysicalAddress;
                DWORD VirtualSize;
                } Misc;
                DWORD VirtualAddress;
                DWORD SizeOfRawData;
                DWORD PointerToRawData;
                DWORD PointerToRelocations;
                DWORD PointerToLinenumbers;
                WORD NumberOfRelocations;
                WORD NumberOfLinenumbers;
                DWORD Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

typedef struct _IMAGE_DATA_DIRECTORY {
                DWORD VirtualAddress;
                DWORD Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;


Portable executable header structures defined by winnt.h

If overlapped, this pair of header fields would point to two different parts of the file, with their sum being the same. Since the sum of these values is the same, the regions would always overlap. And because the sections are loaded from file on disk, this overlap would map the certificate in memory. This would break the assumption of Authenticode being an object present only on disk, and never in memory.

Making these fields overlap is a little more difficult. What’s important to know at this point is how portable executable structures are laid out in memory. This ordering is illustrated by the following graph.

Diagram illustrating a spoofed Authenticode signature on Linux. The image shows a signed executable file passing signature validation, despite being tampered with, due to weaknesses in signature trust validation logic.

The key part is where the section table structure is located. While there are a few ways to calculate its location, the following one is used by the official SDK headers.

#define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER) 
              ((ULONG_PTR)(ntheader) + 
              FIELD_OFFSET( IMAGE_NT_HEADERS, OptionalHeader ) + 
              ((ntheader))->FileHeader.SizeOfOptionalHeader 
))	


The formula takes into consideration that the optional portable executable headers are, well, optional. Allowing for their expansion, the previous structure, file headers, defines their size. With the intent of having a standard way to expand this structure, the expectation is that the value SizeOfOptionalHeaders is always greater than the minimum defined by the standard. However, that isn’t checked by the formula above. It simply expects that the section table is always after the optional headers.

Fiddling with the math a bit, it becomes obvious that for the section headers and the security data directory to overlap perfectly, the value which the SizeOfOptionalHeaders field should have is 0x70. That positions the section and the Authenticode signature location pointers in the described inverse order. And, since this region is skipped during integrity validation, its content is arbitrary.

During the preparation phase, for this Authenticode integrity validation bypass, a simple portable executable file is created. It has a single section with no physical content. Its security directory and section headers overlap. Its image size is sufficient to hold the certificate content after the image is signed. Its code and dependency information are placed within the region of the file that doesn’t yet exist, but will after the file is signed. All of which would make it look like the following image.

osslsigncode authenticode integrity validation

osslsigncode authenticode integrity validation

chktrust authenticode integrity validation

chktrust authenticode integrity validation


Both of these open source tools are victims of improper documentation. There are some unwritten rules when it comes to authenticode integrity validation, prerequisites for which are header malformation checks. Those prohibit overlapping, required by this attack, to occur in the first place. Such signature gets discarded as invalid, which is why Microsoft’s authenticode validation fails to find it even within these specially crafted files.

Unfortunately lack of such header malformation checks is very common. It is, therefore, more than likely that other projects that implement their own Authenticode validation suffer from the same shortcomings. It can be easily checked by the developers and maintainers of such project.

While interesting, this attack isn’t very practical. Because there’s a preparation phase involved, no existing Authenticode signature can be modified without breaking the envelope integrity. Every application signed before this publication remains just as secure as it ever was. Following the best development practices and secure development lifecycle procedures will still result in organizations publishing safe code.

ReversingLabs solutions understand the dangers of extended Authenticode signatures, and they actively prohibit whitelisting when such cases are encountered. More importantly, they alert the developers that such behavior introduces risk, and that it should be avoided. Those notifications are just a small piece of a larger picture in which ReversingLabs solutions enhance secure code development.

Code signing is here to stay, and doing it properly is more important than ever.

Affected products:

osslsigncode
chktrust (.NET Mono toolchain)

Disclosure timeline:

06/24/2019 - Found no contact for osslsigncode (dead project)
06/24/2019 - .NET Core plans on rewriting chktrust before inclusion

Demonstration files:

mono.signed.A.exe - 47B70A4C484C6A00D186B4028B735B3DA24A8EAC53FCB94A73E52BAB091624EA
mono.signed.B.exe - 087F77C03B2B8080B00FFA2543D908B500F209698831789A319117339FE18E6F
oss.signed.A.exe - DA86BBEFBCB4EB8BD68E98C4AFEF9AE4B0742DEBF153681EB6682B3995E00F8E
oss.signed.B.exe - DEC054A93242308E5A9C4D36ED11D35CD1788AC31E6D75853FAAA3C6E94B536F

Keep learning

  • Get up to speed on the state of software security with RL's Software Supply Chain Security Report 2026. Plus: See the the webinar to discussing the findings.
  • Learn why binary analysis is a must-have in the Gartner® CISO Playbook for Commercial Software Supply Chain Security.
  • Take action on securing AI/ML with our report: AI Is the Supply Chain. Plus: See RL's research on nullifAI and watch how RL discovered the novel threat.
  • Get the report: Go Beyond the SBOM. Plus: See the CycloneDX xBOM webinar.

Explore RL's Spectra suite: Spectra Assure for software supply chain security, Spectra Detect for scalable file analysis, Spectra Analyze for malware analysis and threat hunting, and Spectra Intelligence for reputation data and intelligence.

Tags:Threat Research

More Blog Posts

Graphalgo supply chain campaign respawned.

Graphalgo fake recruiter campaign returns

An attack targeting crypto developers has been respawned — with an LLC and new techniques.

Learn More about Graphalgo fake recruiter campaign returns
Graphalgo fake recruiter campaign returns
TeamPCP supply chain attack

The TeamPCP supply chain attack evolves

The malicious campaign started with Trivy and Checkmarx and has shifted to LiteLLM — and now telnix. Here's how.

Learn More about The TeamPCP supply chain attack evolves
The TeamPCP supply chain attack evolves
Malicious npm packages use fake install logs to load RAT

Fake install logs in npm packages load RAT

The final-stage malware in the Ghost campaign is a RAT designed to steal crypto wallets and sensitive data.

Learn More about Fake install logs in npm packages load RAT
Fake install logs in npm packages load RAT
Inside the NuGet hack toolset

Inside the NuGet hackers' toolset

RL discovered two packages containing scripts that complete a typosquatting toolchain. Here's how it worked.

Learn More about Inside the NuGet hackers' toolset
Inside the NuGet hackers' toolset

Spectra Assure Free Trial

Get your 14-day free trial of Spectra Assure for Software Supply Chain Security

Get Free TrialMore about Spectra Assure Free Trial
Blog
Events
About Us
Webinars
In the News
Careers
Demo Videos
Cybersecurity Glossary
Contact Us
reversinglabsReversingLabs: Home
Privacy PolicyCookiesImpressum
All rights reserved ReversingLabs © 2026
XX / TwitterLinkedInLinkedInFacebookFacebookInstagramInstagramYouTubeYouTubeblueskyBlueskyRSSRSS
Back to Top