Posts

2 tiny bugs in sqlmap

I was at SecTalks-Canberra tonight and a workshop was being given on SQL injection. The speaker was talking about sqlmap, so I thought instead of spending the time doing the actual workshop content, which was quite good, I thought would have a quick look at the sqlmap code.

sqlmap/extra/icmpsh/icmpsh-s.c
int main(int argc, char **argv) {
...         unsigned int max_data_size; ...         // parse command line options         for (opt = 1; opt < argc; opt++) {                 if (argv[opt][0] == '-') {                         switch(argv[opt][1]) { ...                                 case 's':                                         if (opt + 1 < argc) {                                                 max_data_size = atol(argv[opt + 1]);                                         }                                         break;
...         in_buf = (char *) malloc(max_data_size + ICMP_HEADERS_SIZE);         out_buf = (char *) malloc(max_data_size + ICMP_HEADERS_SIZE); +++ integer overf…

NetBSD NFS Kernel Vulnerability

This was from InfoSect's first group auditing session.

http://mail-index.netbsd.org/source-changes/2018/01/25/msg091481.html

There must be a lot of embedded NetBSD systems running NFS..

Linux kernel drivers/usb/gadget/function/f_fs.c

static int __ffs_func_bind_do_os_desc(enum ffs_os_desc_type type,
                                      struct usb_os_desc_header *h, void *data,
                                      unsigned len, void *priv)
{
        struct ffs_function *func = priv;
        u8 length = 0;

        switch (type) {

...                 ext_prop->type = le32_to_cpu(desc->dwPropertyDataType);                 ext_prop->name_len = le16_to_cpu(desc->wPropertyNameLength);                 ext_prop->data_len = le32_to_cpu(*(u32 *)                         usb_ext_prop_data_len_ptr(data, ext_prop->name_len));                 length = ext_prop->name_len + ext_prop->data_len + 14;
length is almost certain not able to hold the correct size if name_len and data_len are not small. considering that name_len comes from le16 and data_len comes from le32, it seems likely that they won't always be trivially small.

2 Recent InfoSect CVEs

axmail

In axmail

char username[20];
char fullname[31];
...
        /* Strip SSID */
        if (local) {
                pw = getpwuid(getuid());
        } else {
                strcpy(callsign, call);
                strcpy(username, callsign);
                strlwr(username);
                p = strchr(username, '-');
                if (p) *p = '\0';
                pw = getpwnam(username);
        }
...
                if (local) {
                        strcpy(username, pw->pw_name);
                        strcpy(callsign, username);
                }
                /* Strip full name from the gecos field... */
                if (strchr(pw->pw_gecos, ',') == NULL)
                        strcpy(fullname, pw->pw_gecos);
                else
                        strcpy(fullname, strtok(pw->pw_gecos, ","));

This seems to be a common legacy code bug - assumptions about username/gecos lengths etc.

Forensics Bugs (#2 rifitui)

rifitui is a tool to recover Windows recycle bins.

  int currrecoff;
  int recordsize;

...

  pread( info2_file, fourbytes, 4, 0x0C );
  recordsize = bah_to_i( fourbytes, 4 );

  record = malloc( recordsize );

...

  while (eof == 0) {
    res = pread( info2_file, record, recordsize, currrecoff );
    if (res < recordsize) {
      eof = 1;
    } else {
      filename = record + 0x04;
      index = bah_to_i( record+0x108, 4 );       drive = bah_to_i( record+0x10C, 4 );
      deltime = win_time_to_unix( record+0x110 );       deltm = localtime( &deltime );       year = deltm->tm_year + 1900;       mon = deltm->tm_mon + 1;       sprintf( ascdeltime, "%02d/%02d/%02d %02d:%02d:%02d", mon, deltm->tm_mday, year, deltm->tm_hour, deltm->tm_min, deltm->tm_sec );
      filesize = bah_to_i( record+0x118, 4 );
      printf( "%d%s%s%s%d%s%s%s%d\n", index, delim, ascdeltime, delim, drive, delim, filename, delim, filesize );     }     currrecoff = currrecoff + recordsize;
It's no…

Forensics Bugs (#1 recoverjpeg)

recoverjpeg

    const char *buffer = file_name(dir_format, file_format, begin_index + i);
      i++;
      if (verbose) {
        printf("%s %ld bytes\n", buffer, (long) size);
      }
      fdout = open(buffer, O_WRONLY | O_CREAT, 0666);
      if (fdout < 0) {
        fprintf(stderr, "Unable to open %s for writing\n", buffer);
        exit(1);
      }

...

Writes to an output file (e.g., image00000.jpg) and doesn't check for it being a symlink - hence an attacker could create a symlink pointing to a privileged file that the person running recoverjpeg has write access to. This is mitigated in /tmp /var/tmp by the Linux kernel, but it's still a bug.