Ich möchte für eine Reihe von Zielen (IPs) feststellen, auf welche SMB-Freigaben mein Konto keinen Zugriff hat, auf welche es Lesezugriff hat und auf welche es Lese-/Schreibzugriff hat.
Derzeit verwende ich smbclient. Der Befehl, den ich zuerst ausführe, ist
smbclient -L [targetIP] -U [user] -p 445
Dadurch erhalte ich eine Liste der Freigaben. Beispiel:
Sharename Type Comment
--------- ---- -------
ADMIN$ Disk Remote Admin
C$ Disk Default share
IPC$ IPC Remote IPC
print$ Disk Printer Drivers
MySecrets Disk
Ich kann dann mit diesem Befehl eine Verbindung zu einer Dateifreigabe herstellen
smbclient //[target]/[name_of_share_from_list] -U [user] -p 445
Das Ergebnis ist eine SMB-Eingabeaufforderung. Wenn ich die Eingabeaufforderung eintippe ls
und Dateien sehe, weiß ich, dass ich Lesezugriff habe. Ich schätze, ich muss eine Datei pushen, um zu sehen, ob ich Schreibzugriff habe.
Das ist mühsam. Wie automatisiere ich das, sodass ich für die angegebene Liste von Zielen eine Liste aller Freigaben und die Zugriffsebene meines Kontos darauf erhalte?
Antwort1
Ein Großteil der Arbeit war bereits erledigt. Wenn Sie die Manpage gelesen hätten, smbclient
hätten Sie den Parameter erhalten -c <command>
, mit dem Sie einen oder mehrere Befehle direkt und nicht interaktiv bereitstellen können.
#!/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
Antwort2
VielleichtSMB-Kartekann Ihnen bei dieser Aufgabe helfen. Sein Autor hat es genau zu diesem Zweck entwickelt.
$ 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
Sie können verwenden --host-file
, um eine Liste von Zielen zu übergeben.
Intern versucht es, ein Verzeichnis mit einem zufälligen Namen zu erstellen, um zu überprüfen, ob wir Schreibberechtigungen haben.
Antwort3
Gleicher Ansatz wie akzeptierte Antwort, jedoch unter Verwendungansible. Dies kann dann zum Mounten als Nur-Lese- oder Lese-/Schreibzugriff verwendet werden. (Dadurch können andere Tools wieFusionsfsfunktioniert wie erwartet, wenn eine Vereinigung von Dateisystemen erstellt wird)
- 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