5 ms·
Windows Command-Line Obfuscation
- mdaniel 5y agoBe sure to check out the related blog article at the bottom concerning DLL injection, too -- it is some severe faceplam that "c:\windows \system32\" is considered a trusted directory for auto escalation (after what I presume was `inputdir.ReplaceAll(" ", "").Equals(...)`)
- formerly_proven 5y agoWindows has the additional complication that the arguments of a program are actually handled as a single string, instead of a string array as in Unix, so the programs parse the command line into arguments. This is done by the libc for most programs, but not all programs use that, so there are sometimes differences how the same command line is split into arguments depending on the receiving program. This also means that there are bugs in applications supplying command line flags to other applications due to missing or incorrect quoting, since CreateProcess and .NET Process expect a single string as the command line.
- Arnavion 5y agoIndeed. Splitting, quotes and globs are all handled by the application rather than the shell. Furthermore, you don't just have the two categories of "programs that use libc" and "programs that wing it", but also the third category of "programs that use shell32". Windows ships with two cmdline->argv implementations - one in MSVCRT and the other in shell32. Both are first-party but don't split args the same in all cases.
- silon42 5y agoThere is a great example of "start" command that has a very uncool feature when using double quotes.
- ygra 5y agoThat's a shell built-in, though. So how command-line arguments are handled by processes and the OS doesn't really apply here.
- CyberShadow 5y agoWhat is an example of a command line string that is split differently by Shell32 and MSVCRT? In D, we use CommandLineToArgvW. I'm guessing it's related to Unicode?
- formerly_proven 5y agoMSDN has this blurb with sounds rather... weird to me: > CommandLineToArgvW has a special interpretation of backslash characters when they are followed by a quotation mark character ("). This interpretation assumes that any preceding argument is a valid file system path, or else it may behave unpredictably.
- Arnavion 5y agohttps://github.com/rust-lang/rust/issues/44650 https://github.com/rust-lang/rust/issues/44650 (Nothing to do with unicode. I haven't got a Windows machine to test, but I assume WinMain will behave the same as main wrt quotes and spaces.) (Note that Rust doesn't use CLTAW any more; it switched to "winging it" ie its own implementation. Among other things, this allowed it to drop the dependency on shell32, which is useful for running compiled binaries in nanoserver containers.)
- tinus_hn 5y agoThis also of course leads to inconsistencies in quoting and escaping and makes secure scripting practically impossible. But hey! It certainly was a little easier 30 years ago!
- sebazzz 5y agoThere is an API to get an argc/argv-style list of arguments: https://docs.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-commandlinetoargvw https://docs.microsoft.com/en-us/windows/win32/api/shellapi/... I suppose that is what the C++ runtime uses to feed main/WinMain/_tmain entry points in Win32 programs.
- banana_giraffe 5y agoAlso, as far as I know, there's no "ArgvToCommandLine", at least officially. There is a fairly common one floating around the Internet. That means there are always subtle little gotchas with programs that build up command lines to call other programs.