The MASM Forum Archive 2004 to 2012

General Forums => The Laboratory => Topic started by: hutch-- on May 04, 2005, 04:22:07 AM

Title: What stack exploit ?
Post by: hutch-- on May 04, 2005, 04:22:07 AM
Here is how to solve the problem with any of the masm32 library command line procedures.


; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

comment * -----------------------------------------------------
                        Build this  template with
                       "CONSOLE ASSEMBLE AND LINK"
        ----------------------------------------------------- *

    .code

start:
   
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

    call main

    exit

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

main proc


    .if len(rv(GetCommandLine)) > 128
      print "Warning, Some idiot is trying a stack overflow exploit.",13,10
      ret
    .endif

    cls
    print "Hello World",13,10

    ret

main endp

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

end start


:cheekygreen:
Title: Re: What stack exploit ?
Post by: Mark Jones on May 04, 2005, 05:50:25 AM
Hee hee hee! :)  :U
Title: Re: What stack exploit ?
Post by: QvasiModo on May 05, 2005, 08:52:44 PM
Funny! :bg
Let's just hope no one takes it seriously and believe it's actually a good solution! :bdg
Title: Re: What stack exploit ?
Post by: Ramon Sala on May 06, 2005, 08:16:39 AM
As Quasimodo says, I expect nobody will take that seriously.

Ramon
Title: Re: What stack exploit ?
Post by: hutch-- on May 06, 2005, 08:31:46 AM
Most buffer overflow exploits involve user inputted data to a buffer that is not controlled in its length so if you set up a CGI on the web or have a very high exposure app then it may be vulnerable to someone feeding it more than the buffer allows. This situation is very simple to fix, limit the length but of course there will be other forms of buffer overflow exploits.

I would be interested to hear solutions to other cases.
Title: Re: What stack exploit ?
Post by: AeroASM on May 06, 2005, 12:59:32 PM
Quote from: QvasiModo on May 05, 2005, 08:52:44 PM
Funny! :bg
Let's just hope no one takes it seriously and believe it's actually a good solution! :bdg

I don't get it. What is so funny? Why is it not a good solution?
Title: Re: What stack exploit ?
Post by: Mark Jones on May 06, 2005, 03:17:51 PM
I think QvasiModo meant that the resulting "protection" would be easy to defeat by an experienced cracker?

Personally I find "safeguarding" my executables to be harder than optimizing them. Optimization has its limits - but there's no end to a cracker's infatuation. :(
Title: Re: What stack exploit ?
Post by: QvasiModo on May 06, 2005, 10:22:40 PM
No, I just don't think that limiting command line handling to 128 bytes is good solution, from a design point of view -- I'd just drop the GetCL function entirely. It does fix the problem, the code posted by Hutch is not exploitable at all (no matter how experienced you are).

QuotePersonally I find "safeguarding" my executables to be harder than optimizing them. Optimization has its limits - but there's no end to a cracker's infatuation. :(

So do I :) that's why I prefer string handling functions to enforce text limits (instead of the caller), as well as having those limits configurable (instead of hardcoded into the function).
Title: Re: What stack exploit ?
Post by: hutch-- on May 06, 2005, 10:30:47 PM
Quasimodo,

The GetCL version was written on a win9x box and is dated in 1999 where later OS versions document 32 thousand character command line limits so what I will do when I get the time is produce a table based version for the later OS versions. I could not think of a way to get around checking the command line length but I was interested if anyone else knew of a way to do it as its worth pubishing any tricks like this if it helps.
Title: Re: What stack exploit ?
Post by: QvasiModo on May 06, 2005, 11:09:01 PM
Quote from: hutch-- on May 06, 2005, 10:30:47 PM
The GetCL version was written on a win9x box and is dated in 1999...

Ok, now I understand the text size limit.

Quote...where later OS versions document 32 thousand character command line limits so what I will do when I get the time is produce a table based version for the later OS versions. I could not think of a way to get around checking the command line length but I was interested if anyone else knew of a way to do it as its worth pubishing any tricks like this if it helps.

My two cents: how about leaving this one for backwards compatibility, adding the command line length check inside the function (to secure existing apps without having to change their code), and writing a new function? :)
Title: Re: What stack exploit ?
Post by: hutch-- on May 06, 2005, 11:56:28 PM
i am inclined to leave these old ones as they are and do a new one when I get the time. The design I had in mind was one that uses spaces, tabs and commas as delimiters and handles quoted text as well which is a bit more like programming parsing than command line parsing but I think it will work OK.

There are two choices, my preferred one is to grab each argument as the old ones do as it means you can spot arg 1 to the end in one call but there is another option that takes a little more parsing that is no big deal to do which is to rewrite the buffer so that each argument is zero terminated and load the sum total of addresses into an array of pointers. The new comand line limit of 32 thousand characters can be bashed very quickly if it is done right although I doubt that there is a lot of use for this capacity.
Title: Re: What stack exploit ?
Post by: pbrennick on May 07, 2005, 12:05:23 AM
Hutch,
That is a great idea.  I was just looking at GetCL.asm and it looks like a very well written utility.  Since most of my apps expect a path in the commandline I have the luxury of using PathGetArgs in the shlwapi library.  Did you ever notice that this particular library is just chock full of 'path' stuff?  It might help you in writing your new version.

Anyway, nice utility,
Paul
Title: Re: What stack exploit ?
Post by: Jibz on May 07, 2005, 12:04:17 PM
Making users perform the check on their own is not a fix, it's a workaround :bg.

The first time I brought up the problem (http://www.old.masmforum.com/viewtopic.php?t=3549) (about a year ago), I posted a simple command line parser which creates the C style argv[] array of pointers to command line arguments. Perhaps some of the ideas could be of use in creating the next version?

Either way, I think it's important to fix the problem at the source no matter how many new similar functions are added to the library. And it would not change the functionality other than apps will no longer crash when given too long a command line :green.
Title: Re: What stack exploit ?
Post by: QvasiModo on May 08, 2005, 04:00:37 AM
Quote from: hutch-- on May 06, 2005, 11:56:28 PM
i am inclined to leave these old ones as they are and do a new one when I get the time. The design I had in mind was one that uses spaces, tabs and commas as delimiters and handles quoted text as well which is a bit more like programming parsing than command line parsing but I think it will work OK.

There are two choices, my preferred one is to grab each argument as the old ones do as it means you can spot arg 1 to the end in one call but there is another option that takes a little more parsing that is no big deal to do which is to rewrite the buffer so that each argument is zero terminated and load the sum total of addresses into an array of pointers. The new comand line limit of 32 thousand characters can be bashed very quickly if it is done right although I doubt that there is a lot of use for this capacity.

I have a FASM routine that goes half that way: turns a given ASCIIZ string into an ASCIIZ array (strings one next to the other, ends with a double NULL). Traversing the array forward is fairly trivial, and the code size is small. I also think speed is not important, even with 32k command lines (which are going to be rare anyway). I can post it here if you want to take a look. :)
Title: Re: What stack exploit ?
Post by: hutch-- on May 08, 2005, 05:20:47 AM
Jibz,

What if the user wants a 32 character limit ? use5r defined methods are more flexible, especially when you are dealing with assembler programmers.

QvasiModo,

Thanks for the offer, it will be worth having a look at. I am currently working on the version that grabs a single argument if it exists as I find this type more useful but the other design is also very useful for very long command lines. About the only problem I see is knowing how large to make the array to hold the pointers to each word start on the command line. Probably a user defined limit with the array is the safest way to go as the user should have some idea of the maximum number of arguments that the program will accept.
Title: Re: What stack exploit ?
Post by: Jibz on May 08, 2005, 09:00:37 PM
I think it would be a bad idea to stuff another one with some static limit into the library. The user doesn't always know a fixed limit either, e.g. build tools must handle any number of obj files you throw at them.

I would prefer some design that will allow any length and number of command line arguments :U.
Title: Re: What stack exploit ?
Post by: hutch-- on May 11, 2005, 01:47:00 PM
Jibz,

The reference material says there is an absolute limit of 32k characters so there cannot be such a thing as an unlimited command line length.
Title: Re: What stack exploit ?
Post by: QvasiModo on May 11, 2005, 06:04:25 PM
Quote from: hutch-- on May 11, 2005, 01:47:00 PM
Jibz,

The reference material says there is an absolute limit of 32k characters so there cannot be such a thing as an unlimited command line length.
There could be in the future, though. Or the limit could be expanded again. It's probably better to be on the safe side and let the user decide the limit, IMHO.
Title: Re: What stack exploit ?
Post by: QvasiModo on May 12, 2005, 09:04:57 PM
My apologies for taking so long to post, had some problems with my computer back home.

Here's the code, it's FASM syntax, should be easy to port and adapt to the winapi calling convention. I'd also add some code to get the commandline string, make a copy (allocated with HeapAlloc), and resize the memory object at the end of the routine.

;-----------------------------------------------------------------------------
; Command line parser by QvasiModo.
; Turns the string pointed to by EBX into an ASCIIZ array in place.
; Recognizes parameters enclosed in double quotes as a single token.
; Destroys EBX, ESI y EDI.
; NOTE: The GetCommandLine API returns a string that should be
; considered READ-ONLY. Make a copy of it before calling this proc.
tokenizar:
        mov     edi, ebx

.token_espacios:                        ; Skip spaces between tokens.
        movzx   eax, byte [ebx]
        add     ebx, 1
        test    eax, eax
        jz      .token_fin
        cmp     eax, ' '
        je      .token_espacios
        cmp     eax, '"'
        je      .token_comillas

.token_palabra:                         ; Search for the end of a word.
        lea     esi, [ebx - 1]
@@:     movzx   eax, byte [ebx]
        add     ebx, 1
        test    eax, eax
        jz      .token_copiar
        cmp     eax, ' '
        jne     @b
        jmp     .token_copiar

.token_comillas:                        ; Search for the end of a quoted string.
        mov     esi, ebx                ; Special case: "" is ignored.
        movzx   eax, byte [ebx]
        add     ebx, 1
        cmp     eax, '"'
        je      .token_espacios
        test    eax, eax
        jz      .token_fin
@@:     movzx   eax, byte [ebx]
        add     ebx, 1
        test    eax, eax
        jz      .token_copiar
        cmp     eax, '"'
        jne     @b

.token_copiar:                          ; Copy a token in [EDI].
        mov     byte [ebx - 1], 0       ; [ESI] -> beginning, [EBX - 1] -> end.
        xor     eax, eax
@@:     mov     al, byte [esi]
        mov     byte [edi], al
        add     esi, 1
        add     edi, 1
        cmp     al, 0
        jne     @b
        jmp     .token_espacios

.token_fin:                             ; We're done!
        mov     byte [edi], 0
        ret

Hope it's of any use! :)
Title: Re: What stack exploit ?
Post by: Jibz on May 12, 2005, 09:10:40 PM
Nice .. is there some way to escape a double quote to insert it into an argument?

I mean something like: "this arg with spaces contains \" characters"
Title: Re: What stack exploit ?
Post by: QvasiModo on May 12, 2005, 09:15:53 PM
No, I wrote it originally to receive filenames only. But it's a good idea. :)
Title: Re: What stack exploit ?
Post by: Mark Jones on July 21, 2006, 11:55:22 PM
Does anybody know, in the pointer that GetCommandLine returns, is the file executed ALWAYS surrounded in quotes, i.e.


00141EE0  22 43 3A 5C 44 57 47 2E 65 78 65 22 20 22 63 3A  "C:\abc.exe" "c:
00141EF0  5C 70 72 6F 67 72 61 6D 20 66 69 6C 65 73 5C 66  \program files\f
00141F00  72 65 6C 6C 2E 65 78 65 22 20 2F 61 72 67 3A 77  rell.exe" /arg:w
00141F10  68 6F 61 00 AB AB AB AB AB AB AB AB EE FE EE FE  hoa.««««««««îþîþ


Here "C:\abc.exe" is the file being debugged and its name is quoted, even though it doesn't have to be. Can I expect all versions of windows to behave the same way? Because it would be convenient to just scan for the 2nd instance of the quotation character to determine where the real arguments begin. Thanks!
Title: Re: What stack exploit ?
Post by: hutch-- on July 22, 2006, 12:16:50 AM
Mark,

It appears to vary from OS version  to OS version and about the only safe way I know of handling this variation is to deal with either quoted blocks or normal blocks of text at the same time.


"drv:\path\my app with spaces.exe" arg1 "quoted text" arg3 "more quoted" arg5

becomes

"drv:\path\my app with spaces.exe"
arg1
"quoted text"
arg3
"more quoted"
arg5
Title: Re: What stack exploit ?
Post by: Mark Jones on July 22, 2006, 07:51:38 AM
Interestingly, when ran from a console prompt instead of start-->run, the returned argument filename is not quoted and is lacking an extension, i.e.,


00141EE0  44 57 47 20 22 63 3A 5C 70 72 6F 67 72 61 6D 20  abc "c:\program
00141EF0  66 69 6C 65 73 5C 66 72 65 6C 6C 2E 65 78 65 22  files\frell.exe"
00141F00  20 2F 61 72 67 3A 77 68 6F 61 00 AB AB AB AB AB  /arg:whoa.««««««


I'm assuming that either one of these two behaviors can be expected on most versions of windows... because parsing this is a requirement of DWG, hopefully I've implemented a tiny and lightweight method in the DWG project:
http://www.masm32.com/board/index.php?topic=5317.0
Title: Re: What stack exploit ?
Post by: zooba on July 22, 2006, 11:43:04 AM
It's easy to deal with. While parsing, every time you encounter a quote, toggle a bit/byte/flag somewhere. If the flag is set, spaces are part of the argument; if the flag is clear, spaces delimit the arguments. Then you can check for quotes surrounding a parameter and remove them if desired.

Cheers,

Zooba :U