3

For a series of targets (IPs), Id like to determine which SMB shares my account has no access to, which it has read access to, and which it has read/write access to.

Currently I am using smbclient. The command I run first is

smbclient -L [targetIP] -U [user] -p 445

This gives me a list of shares. For example;

        Sharename       Type      Comment
        ---------       ----      -------
        ADMIN$          Disk      Remote Admin
        C$              Disk      Default share
        IPC$            IPC       Remote IPC
        print$          Disk      Printer Drivers
        MySecrets       Disk

I then can connect to a file share with this command

smbclient //[target]/[name_of_share_from_list] -U [user] -p 445

Which results in an SMB prompt. From the prompt I type ls and if I see files I know I have read access. I'm guessing I have to push a file to see if I have write access.

This is tedious. How do I automate this such that for the given list of targets, I get a list of all shares, and the level of access my account has to them?

3 Answers 3

7
+50

You had much of the work already in place. Reading the man page for smbclient would have given you the -c <command> parameter, which can be used to provide one or more commands directly rather than interactively.

#!/bin/bash
username="DOMAIN\\USER"    # Double backslash
password="PASSWORD"        # For demonstration purposes only
hostname="TARGET_HOST"     # SMB hostname of target

cd "${TMPDIR:-/tmp}"
touch tmp_$$.tmp           # Required locally to copy to target

smbclient -L "$hostname" -g -A <( echo "username=$username"; echo "password=$password" ) 2>/dev/null |
    awk -F'|' '$1 == "Disk" {print $2}' |
    while IFS= read -r share
    do
        echo "Checking root of share '$share'"

        if smbclient "//$hostname/$share/" "$password" -U "$username" -c "dir" >/dev/null 2>&1
        then
            status=READ

            # Try uprating to read/write
            if smbclient "//$hostname/$share/" "$password" -U "$username" -c "put tmp_$$.tmp ; rm tmp_$$.tmp" >/dev/null 2>&1
            then
                status=WRITE
            fi
        else
            status=NONE
        fi

        case "$status" in
            READ) echo "Well, $username has read access" ;;
            WRITE) echo "Yes, $username has write access" ;;
            *) echo "No, $username has no access" ;;
        esac
    done

rm -f tmp_$$.tmp
12
  • Ah i was wondering if id have to resort to a bash script like this. I havent written one yet but this may give me a good starting point. Can you edit this to output if i have read access only? Commented May 30, 2017 at 15:28
  • In addition to the check for write as well i mean Commented May 30, 2017 at 15:29
  • @n00b. You could change the second echo putting the message "$username has read-only access to the root of this share". Unless you are also scanning directories that you have no read access at all... Commented May 30, 2017 at 20:16
  • The later is the case. I dont know if I have read access, and would rather have the option to 'try writing' after knowing if I have read access first. In otherwords, tell me if I have read first, then tell me if I have write. Is that possible? Commented May 30, 2017 at 21:06
  • 1
    @roaima I did. I saved it in a script.sh file, ran the chmod 755 script.sh command then am trying to execute ./script.sh but it just sits and sits. I added echo 'breadcrumbs' and the echos execute up until the smbclient line Commented Jul 5, 2017 at 21:14
3

Maybe SMBmap can help you with this tastk. Its author developed it precisely for that purpose.

$  python smbmap.py -H [targetIP] -u [user] -P 445
[+] Finding open SMB ports....
[+] User SMB session establishd...
[+] IP: 192.168.0.4:445 Name: 192.168.0.4
        Disk                                                    Permissions
        ----                                                    -----------
        ADMIN$                                                  READ, WRITE
        C$                                                      READ, WRITE
        IPC$                                                    NO ACCESS
        TMPSHARE                                                READ, WRITE     

You can use --host-file to pass a list of targets.

Internally, it tries to create a directory with a random name to check if we have write permissions.

0

Same approach as accepted answer but using ansible. This can then be used for mounting as read-only or read-write. (Which then makes other tools such as mergerfs work as expected when a union of filesystems is created)

- name: get available samba shares
  ansible.builtin.shell:
    cmd: "smbclient -L //{{ samba_ip }} -U % -g | grep Disk"
  register: samba_shares_raw

- name: extract samba shares
  ansible.builtin.set_fact:
    samba_shares: "{{ (samba_shares | default([])) + [ ( item | split('|') )[1] ] }}"
  loop: "{{ samba_shares_raw.stdout_lines }}"

- name: send a file to test ro / rw access
  ansible.builtin.file:
    path: "{{ ansible_env.HOME }}/samba_client"
    state: touch

- name: test writeable samba
  ansible.builtin.shell:
    cmd: "smbclient -U % //{{ samba_ip }}/{{ item }} -c 'put samba_client'"
    chdir: "{{ ansible_env.HOME }}"
  register: writeable_raw
  ignore_errors: true
  loop: "{{ samba_shares }}"

- name: extract writeable results
  ansible.builtin.set_fact:
    writeable: "{{ writeable | default({}) | combine({ item.item : not item.failed }) }}"
  loop: "{{ writeable_raw.results }}"
  loop_control:
    label: "{{ item.item }}"

- name: samba mount directories
  ansible.builtin.file:
    state: directory
    recurse: true
    path: "{{ ansible_env.HOME }}/samba/{{ item }}"
  loop: "{{ samba_shares }}"

- name: mount samba shares
  ansible.posix.mount:
    src: "//{{ samba_ip }}/{{ item }}"
    path: "{{ ansible_env.HOME }}/samba/{{ item }}"
    fstype: cifs
    opts: "{{ 'rw' if writeable[item] else 'ro' }},guest,uid=1000,gid=1000"
    state: mounted
  loop: "{{ samba_shares }}"
  become: true

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.