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 ls
e 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 smbclient
forneceria 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-file
para 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