Excellent Conversions (and downloads)

This one was on a back burner for a while too.

C:\Program Files*\Microsoft Office\root\Office*\excelcnv.exe is a program that helps to convert various documents to XLSX format. While playing around with it I noticed it accepts URLs hence you can use it to download stuff from the internet. The caveat is that this downloaded data will be stored inside a UTF8-encoded stream embedded inside the XLSX Zip archive.

Example binary data (favicon.ico):

and data downloaded as a stream:

The command line arguments for excelcnv.exe are not documented well. Many examples online refer to “-oice” argument followed by the input and output file names. That’s it. And yeah, this actually works, so since I have already mentioned that input parameter can be an URL, the downloader invocation can be as follows:

excelcnv.exe -oice <URL> <OUPUT>

Still, there is more to discover.

For instance, what the heck is ‘oice’? After googling around I eventually discovered it stands for Office Isolated Conversion Environment.

Other interesting stuff to look at are other, undocumented command line arguments used by excelcnv.exe – these I found so far are as follows:

  • -oics – don’t know how it is being used at the moment
  • -bcs – you can use it to convert INPUT file to .ods e.g.
    • excelcnv.exe -bcs <XLSX> <ODS>
  • -repair
  • -o – orientation (for PDF)
  • -ps – paper size (for PDF)
  • -dps – default paper size (for PDF)
  • -scl – scaling option (for PDF)
  • -wtp – what to print (for PDF)
  • -preview – preview quality (for PDF)
  • -pofo – automatic print on file open (for PDF)
  • -nafap – use named action setting (for PDF)
  • -pglim – page limit (for PDF)
  • -rv – unknown (for PDF)

There are probably more, but this is what I explored so far.

The default OUTPUT file type is XLSX. The file format can be changed using a dedicated file extension accepted by the program:

  • .xltx
  • .xlam
  • .xlsm
  • .ods
  • .xls*
  • .pdf
  • .xlsx
  • .png
  • .jpg

but not sure yet how to use all of them as not all of them worked for me (good news is that all the *.xl* work well with “-oice” command).

BYOT – Bring Your Own Telemetry

Update 2023-11-15

Greg posted this finding on Twitter/X today and I have updated the below list accordingly. Thanks!

Old Post

Research is a funny business. You look at some stuff, you conclude it’s impossible, and then… you forget about it. So you think. It gets stuck in your head… somewhere… so that you can come back to it one day.

For CompatTelRunner.exe this day is today.

When I looked at this program a few years ago I saw it has a great LOLBIN potential. It takes two arguments -m for module, and -f for exported API function name. Nothing could be better than that, right?

You just invoke:

CompatTelRunner.exe -m:foo.dll -f:bar

and it will load foo.dll and call the bar api!

The problem is that programmers of this tool anticipated this sort of abuse and built-in some code to block it, and:

  • made sure the DLLs are loaded from the system directory, and
  • path to the system directory is retrieved via GetSystemDirectory API, and
  • they also check the -m argument is one of:
    • aemarebackup.dll
    • appraiser.dll
    • generaltel.dll
    • invagent.dll
    • devinv.dll
    • aeinv.dll
    • aepic.dll
    • pcasvc.dll, and
  • finally they also check the -f argument is one of:
    • BackupMareData
    • DoScheduledTelemetryRun
    • UpdateAvStatus
    • RunGeneralTelemetry
    • DoCensusRun
    • RunInUserCxtW
    • RunUpdate
    • GetFileSigningInfo
    • CreateDeviceInventory
    • UpdateSoftwareInventoryW
    • UpdateSoftwareInventory
    • GetCITData
    • QueryEncapsulationSettings

Bummer.

Today it crossed my mind that I never checked if we can find these DLLs in both System32 and SysWOW64 directories. I hypothesized that maybe one of the 32-bit ones is missing and we could place our own there. I quickly checked and found out far more than I anticipated – from the list of all .exe and .dll listed above I could only find the following:

  • \Windows\System32\CompatTelRunner.exe
  • \Windows\System32\appraiser.dll
  • \Windows\System32\generaltel.dll
  • \Windows\System32\invagent.dll
  • \Windows\System32\devinv.dll
  • \Windows\System32\aeinv.dll
  • \Windows\System32\aepic.dll
  • \Windows\System32\pcasvc.dll
  • \Windows\SysWOW64\aepic.dll

As you can see, almost none of these allowed DLLs are present in the SysWow64 directory. And, there is no sign of 32-bit CompatTelRunner.exe either.

Since…

I decided to borrow one from 32-bit version of Windows 10 and placed it in c:\test. I then created my test c:\WINDOWS\SysWOW64\appraiser.dll and ran:

CompatTelRunner.exe -m:appraiser.dll -f:DoScheduledTelemetryRun

Once my test 32-DLL got loaded, I could see its debug message in Debug View:

It’s nothing groundbreaking and I abused subtle differences between Syswow64 and System32 many times before it’s still fun to discover more of them over and over again.