{"id":9694,"date":"2024-11-30T10:40:12","date_gmt":"2024-11-30T10:40:12","guid":{"rendered":"https:\/\/www.hexacorn.com\/blog\/?p=9694"},"modified":"2024-12-25T23:18:53","modified_gmt":"2024-12-25T23:18:53","slug":"1-little-known-secret-of-shellexec_rundll","status":"publish","type":"post","link":"https:\/\/www.hexacorn.com\/blog\/2024\/11\/30\/1-little-known-secret-of-shellexec_rundll\/","title":{"rendered":"1 little known secret of ShellExec_RunDLL"},"content":{"rendered":"\n<p>The <em>ShellExec_RunDLL<\/em> API is now exposed by both <em>shell32.dl<\/em>l and <em><a href=\"https:\/\/www.hexacorn.com\/blog\/2024\/11\/28\/windows-storage-lol\/\" data-type=\"post\" data-id=\"9685\">windows.storage.dll<\/a><\/em>.<\/p>\n\n\n\n<p>It is not the only curiosity about this function. Analysing its code one can discover that is accepts a secret command line argument.<\/p>\n\n\n\n<p>If we provide a question mark in the command line argument, the function will interpret the string that follows the question mark as a number. It will then convert that numerical value into a number using StrToIntExW with a STIF_SUPPORT_HEX flag (accepts either decimal or hexadecimal number), and then add that value to 0x100 (SEE_MASK_NOASYNC\/SEE_MASK_FLAG_DDEWAIT). Finally, use the resulting total to set the SHELLEXECUTEINFO.fMask value passed to <em>ShellExecuteEx<\/em>. The function then searches for the second question mark and then uses the position following that question mark as a place where the actual command line passed to <em>ShellExecuteEx<\/em> starts:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2024\/11\/ShellExec_RunDLL.png\"><img decoding=\"async\" loading=\"lazy\" width=\"668\" height=\"513\" src=\"https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2024\/11\/ShellExec_RunDLL.png\" alt=\"\" class=\"wp-image-9695\" srcset=\"https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2024\/11\/ShellExec_RunDLL.png 668w, https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2024\/11\/ShellExec_RunDLL-300x230.png 300w, https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2024\/11\/ShellExec_RunDLL-391x300.png 391w\" sizes=\"(max-width: 668px) 100vw, 668px\" \/><\/a><\/figure>\n\n\n\n<p>If it sounds too complicated, the basic idea is that function can be invoked in 2 modes:<\/p>\n\n\n\n<ul>\n<li>regular invocation<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">shell32.dll, ShellExec_RunDLL &lt;cmd line argument&gt;<br>windows.storage.dll, ShellExec_RunDLL &lt;cmd line argument&gt;<\/pre>\n\n\n\n<ul>\n<li>invocation that modifies fmask<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">shell32.dll, ShellExec_RunDLL &lt;?fmaskvalue?&gt; &lt;cmd line argument&gt; \nwindows.storage.dll, ShellExec_RunDLL &lt;?fmaskvalue?&gt; &lt;cmd line argument&gt;<\/pre>\n\n\n\n<p>f.ex.:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">ShellExec_RunDLL ?100?calc.exe<\/pre>\n\n\n\n<p>And if you are looking for a better example:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">ShellExec_RunDLL ?0x00800000?&lt;file><\/pre>\n\n\n\n<p>can be used to bypass <em>Zone.Identifier<\/em> checks (0x00800000 = SEE_MASK_NOZONECHECKS) for the executed <em>file<\/em>.<\/p>\n\n\n\n<p>Since the parsing of the fmask value is done with a code that allows for many different inputs, many interesting invocations are possible:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">ShellExec_RunDLL ?100?calc.exe\nShellExec_RunDLL ? 100 ?calc.exe\nShellExec_RunDLL ? 0x100 0x200 ?calc.exe\nShellExec_RunDLL ?0x100 notepad.exe?calc.exe\nShellExec_RunDLL ?0x100 format c: ?calc.exe\nShellExec_RunDLL ?0x100 https:\/\/google.com ?calc.exe\nShellExec_RunDLL ?0x100 c:\\programdata\\malware\\calc.exe ?calc.exe<\/pre>\n\n\n\n<p>Every single one of them will launch Calculator.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The ShellExec_RunDLL API is now exposed by both shell32.dll and windows.storage.dll. It is not the only curiosity about this function. Analysing its code one can discover that is accepts a secret command line argument. If we provide a question mark &hellip; <a href=\"https:\/\/www.hexacorn.com\/blog\/2024\/11\/30\/1-little-known-secret-of-shellexec_rundll\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[126,56,64],"tags":[],"_links":{"self":[{"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/posts\/9694"}],"collection":[{"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/comments?post=9694"}],"version-history":[{"count":4,"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/posts\/9694\/revisions"}],"predecessor-version":[{"id":9699,"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/posts\/9694\/revisions\/9699"}],"wp:attachment":[{"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/media?parent=9694"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/categories?post=9694"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/tags?post=9694"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}