Determinar compartilhamentos SMB aos quais tenho acesso de leitura e/ou gravação

Determinar compartilhamentos SMB aos quais tenho acesso de leitura e/ou gravação

Para uma série de alvos (IPs), gostaria de determinar a quais compartilhamentos SMB minha conta não tem acesso, a quais ela tem acesso de leitura e a quais ela tem acesso de leitura/gravação.

Atualmente estou usando o smbclient. O comando que executo primeiro é

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

Isso me dá uma lista de compartilhamentos. Por exemplo;

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

Posso então me conectar a um compartilhamento de arquivos com este comando

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

O que resulta em um prompt SMB. No prompt eu digito lse se vejo arquivos sei que tenho acesso de leitura. Acho que preciso enviar um arquivo para ver se tenho acesso de gravação.

Isso é tedioso. Como posso automatizar isso de forma que, para uma determinada lista de alvos, eu obtenha uma lista de todos os compartilhamentos e o nível de acesso que minha conta tem a eles?

Responder1

Você já tinha grande parte do trabalho em andamento. A leitura da página de manual smbclientforneceria o -c <command>parâmetro, que pode ser usado para fornecer um ou mais comandos diretamente, em vez de interativamente.

#!/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

Responder2

TalvezMapa SMBpode ajudá-lo com esta tarefa. Seu autor o desenvolveu justamente para esse fim.

$  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     

Você pode usar --host-filepara passar uma lista de alvos.

Internamente, tenta criar um diretório com um nome aleatório para verificar se temos permissões de escrita.

Responder3

Mesma abordagem da resposta aceita, mas usandoansible. Isso pode então ser usado para montagem como somente leitura ou leitura-gravação. (O que torna outras ferramentas, comofusõesfuncionam conforme o esperado quando uma união de sistemas de arquivos é criada)

- 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

informação relacionada