Sparc Flow – what a read …

As some of my readers may know I have a certificate on ISO/IEC 27001 internal auditing. (Not that there are many customers interested in this … security in Germany still is a waste land.) The ISO/IEC 27001 standard defines a systematic process oriented approach to security. At its core it demands (besides other things) defined processes for a thorough periodical risk analysis to derive appropriate security measures. Control, audit and continuous improvement processes must be included in the process landscape – up to highest company level. So far so good. Of course, technical measures have to be taken into account – but the whole “control” catalog of Appendix A is written in a very general way and has to be broken down to specific requirements of a company.

Despite working on process consulting, I carry around a technical mindset from my time in physics and numerical math. So, in a way, I like looking at the technical basics in a security context – though I would not call me a real technical expert on “hacking”. Still I have a profound interest in pen-testing tools. In my opinion every type of security auditor should have a reasonable amount of knowledge about technical risks, pen-testing and possible attack vectors. However, after working a while with common scanning and attack tools in isolated pen-test environments – with the legal consent of the owners – one gets a strange feeling:

When you judge the effectiveness of security measures and test them by standard analysis tools: Don’t you miss the creativity of real hackers? Are the “real” threats covered by pen-testing tools like vulnerability scanners and Metasploit stuff, at all?

Another critical point is the threat level assigned by tools like Nessus or OpenVAS to detected system vulnerabilities – if you concentrate on the most “severe”, high point alerts, you may almost always miss some “low” risks and underlying threats, which alone or in combination can be used for a systematic privilege escalation. That there is some truth in this statement you may already find out on metasploitable training machines.

So, one of the questions nagging in a corner of my mind from time to time was: Is there some literature which gives you a broader insight in the way a hacker may think? In action? Yesterday, I started reading a series of books of an author calling himself “Spark FLOW”.

My preliminary “verdict” as a non-hacker, but as a defense and security oriented person after 2 out of 7 books is:

Very interesting reading – though based on somewhat “constructed” scenarios (so far). Creative, varying use/combination of attack methods on different types of machines … I learned quite a bit about some Windows weaknesses and privilege escalation. But also Linux gets its amount of hacks and related comments. It is almost provocative that the first book rather early describes compromising a Linux machine in a DMZ ….(because – as the author explains in a footnote – “otherwise it would be too simple if we directly landed on Windows from the start”).

However, more important: Although written very attack-oriented – it gave me a hell to think about counter-measures. Which I, probably, have a better grasp on regarding Linux machines. But there a some Windows systems in our nets, too.

I would like very much to see a kind of summary table of this guy at the end of each of his books with a systematic collection of weaknesses and vulnerabilities exploited – and his ideas on reasonable countermeasures on the admins’ side.

Anyway – the reading was “enjoyable” and a bit frightening at the same time. It triggers some serious thinking. I recommend the book series of Sparc Flow to all “admins” and to all “sec staff” members who want to learn more about a hacker’s mindset and its flexibility.

Leaving Facebook … – I

At the beginning of this year I got advice from several people to become a customer of Facebook. I thought this could be interesting – what would it feel like? Especially, as I am biased – against data collectors … And I knew the GDPR of the EU (DSGVO in Germany) would come soon … Would be interesting to see how FB would react …

My wife – a Norwegian citizen – is very active on Facebook and Instagram. One reason is that she, of course, is interested in current developments in her home country. My grandchildren are on Instagram. Some friends are on Facebook – mostly as private persons. So, there are obviously some points that at least count for other people in favor of FB. Among other things: FB offers “free” communication services. And it offers information spreading – on fast time scales. Yeah, well known … A fundamental question, however, is: Information spreading to whom?

As some people may have noticed: I have left Facebook two days ago – for good. As I have no other platform, yet, I want to explain my decision here.

Personal Experience – a summary

I have tried and used FB now for 4 months. My personal opinions and conclusions are:

  • FB comprises a totally unproductive bubble world on a headline level.
  • It costs you a lot of time and delays productivity of whole societies.
  • Instagram appears to make children and teens addicted. A whole generation is literally wasting its youth with FB products.
  • In a way Facebook undermines the business of serious news agencies.
  • It is manipulative and provokes you to publish opinions – without any filter.
  • It is definitely a machinery aggregating detailed profile information on individuals of big parts of the world’s population.

So, FB, for me is at least as bad as expected – if not worse. But last things first.

The new terms and regulations as part of FB’s reaction to the EU GDPR

At least after the EU’s GDPR ( FB became relatively clear about what information it gathers on you. By providing you – at least in principal – with information on new terms and rules. Which you must accept, if you want to continue using FB services.

They are, however, not so clear about how they earn money with their services – and who really gets your data. Should make you suspicious. Despite all efforts to create a certain impression: FB is NOT a welfare company. So, take your time and read the new terms very carefully … No, its no fun; if printed, its a lot of pages in tiny letters …

Whilst you read keep in mind that FB already transferred 1,5 to 1,8 billion data records on non EU-customers to the US – where the information provision is not regulated as it soon will be in the EU.

“Data Policy” information – how to find it
So how do you as a EU citizen get to information of how FB uses data about and on you:

To see the full extent you have to move to your account, down to the left side – Link “impressum/terms/NetzDG”. Then you get to a page with the old rules; but at the top there is a warning about imminent changes – and a link to the new rules. Click there – navigate a bit – yes, there is a link for a printable version on the left side. Get the whole stuff printed on at least 7 pages in a quite tiny font size. Read … and get reminded of the Windows 10 user conditions.

My short summary is – and please correct me, if you find something which you think cannot be interpreted the way I see it:

What data, where from?
FB gathers all information on you which it can get – from all types of sources, including other persons and services besides FB’s own applications.
About what you do, where you do it, when, and not surprisingly for data analysts, how you do it (when you interact with their pages, e.g. via mouse or finger movement, scrolling analysis, …).

They collect detailed information about all devices you use and – as far as possible – also on processes running there as well as on configuration settings. They collect data that identify these devices and their settings in a unique way – and which identify, thereby, also you as a person, your location and parts of your behavior, plus your relation to your Internet providers. They use face recognition techniques if allowed on your device or if you accepted conditions to do so whilst using a FB product. FB clearly says that it combines all this gathered information. Across all of their products you may use (FB, Instagram, Whatsapp, Oculus, …). Not excluding other secondary sources and resources – as “partners” on whose websites you may have been.

And because FB is such a welfare oriented company it also does the following; I quote:

“We use the information (including your activities off our Products, such as websites you visit and ads you see) to help advertisers and other partners measure the effectiveness and distribution of their ads and services, and understand the types of people who use their services and how people interact with their websites, apps and services.”

Please note the “off” (2 fs !) in the first sentence. And the remarkable word “partners”. Hmm, there are “partners” and there are “third-party partners” as we soon learn. Notably, FB does not mention any money here. And of course not, where FB and their “partners” pay tax for all this “help”.

Yeah, … And of course your data may be used in projects and research in the context of “general social welfare, technological advancement, public interest, health and well-being”. Unfortunately, you have to assume that FB itself defines the meaning and borders of all these nice words … especially “public interest”. These expressions are not explained and left open – what an arrogance!

Then we learn throughout paragraph III that YOU as a user should think carefully about whom you share information with – because you may loose control over your data. Oooops … in the end data protection is still my own responsibility – and shit happens as we all know ….

Third-party partners
And then (2 pages later) comes a very nice and very fine distinction:
The “third-party partners.” And, within this context, we almost cannot believe it:

“We don’t sell any of your information to anyone, and we never will. We also impose strict restrictions on how our partners can use and disclose the data we provide. Here are the types of third parties we share information with …”.

You can almost see the lawyer who has written this. From the context it should become clear that this is only about “third-party partners” – and maybe not a general statement on other types of (direct) “partners”. Otherwise, FB would have to explain, where all the billions do come from, every year, … I would say – an unexplained business is a kind of dubious business.

Another pretty creepy part in this paragraph is the following – see the lines under “Measurement partners”: “We share information about you with companies that aggregate it to provide analytics and measurement reports to our partners.”

Wow … Read it again and again … It is not (!) Facebook that aggregates – it is some other companies! Meaning these other companies first get personal data about you which they then (!) aggregate and provide back to FB’s partners. You see the funny lawyer again, which I mentioned above. I hope the EU data protection authorities have a very close look into this type of information provided by FB.

And then again the welfare attitude:
“We also provide data and content to research partners and academics to conduct
research that advances scholarship and innovation that support our business or mission, and enhances discovery and innovation on topics of general social welfare, technological advancement, public interest, health and well-being.”

Didn’t you always want to become a subject for some special analysis? Hey, you can get famous – somewhere in some data lab …

Cooperation with law enforcement
Pretty nice also some passages about sharing data with law enforcement institutions: Here we learn that the exchange of data is based on “good-faith belief” on FB’s side. You do not believe it? Read paragraph VIII of the whole mess yourself. And good luck, if you, e.g., happen to be Russian or Chinese …

Addendum, 04/28/2018: What is not written in the new Data Policy

As with other business it is interesting, too, what is not written down explicitly. In this case in the FB document on “Data Policy”.

E.g., you do not get information on who are “partners” – and what makes a “partner” a partner of FB. Also, the definition of a “third-party partner” is pretty unclear. So, in the end you do not know where your data end up – or who under which conditions employees of partners and third-party partners get access to them.

The other remarkable thing is: It is not written where FB stores your data and what they do for data protection – technically and otherwise. You may assume from newspaper articles that your data should be located on servers within the EU, especially in Ireland. But, you have no guarantee for this.

You may nail the whole mess down with some simple questions: How can you as a EU citizen be sure that there, e.g., is no copy of all your collected data on a Russian FB server – and/or that there is no Russian “partner” or “third-party partner”, who is allowed to get your personal data for “aggregation” and “research” in the “public interest” of Russia? My copy of the present “Data Policy” of FB does not seem to exclude such a type of scenario – if I assume that there are some Russian partners of FB. Are there? I would like to know .. Of course, I have learned that the data would not be “sold” to third-party partners or authorities … but maybe just given – in “good-faith belief” …

A last remarkable thing is that you do not find a single description about variants and functionality of AI and deep learning algorithms FB or their aggregating partners or third-party partners use. So, besides not knowing where your data end up, you neither get to know in which way and for which special purpose your data get analyzed.


Facebook is and remains creepy. Its information on what customer data they gather and what they in general do with it is partially quite open and partially very obscure and evasive. In my opinion. Some paragraphs in the “Data Policy” open up a legal void – with much room for interpretation.

Taking it all together, I see a fundamental lack of understanding at FB what data privacy really means – and how it should be described for customers. But there is one thing I must admit: FB warns you – in a way – that you should be careful about what you share on Facebook.

You should take this warning seriously. And read a comment of the well known security expert and researcher Bruce Schneier on the whole information gathering industry around FB and others; his comment was published on CNN:

Bruce Schneier on Facebook and CA

Read also about the EU GDPR and its intentions:

See also:

Mounten eines vmdk-Laufwerks im Linux Host – IV – guestmount, virt-filesystems, qemu-img

In den vorhergehenden Beiträgen dieser Serie

Mounten eines vmdk Laufwerks im Linux Host – I – vmware-mount
Mounten eines vmdk-Laufwerks im Linux Host – II – Einschub, Spezifikation, Begriffe
Mounten eines vmdk-Laufwerks im Linux Host – III – qemu-nbd, loop-devices, kpartx

hatten wir gesehen, dass der Zugang zu komplexen vmdk-Images mit Snapshots, Extents und Base-Disk Files eine Kontrolle über das vmdk-Format und die zugehörige Block-Adressierung erfordert. Die notwendigen Informationen sind ggf. über mehrere Files in unterschiedlichen Ästen des Filesystems eines Hosts verteilt; eine Verwendung unter Linux erfordert daher einen zwischengeschalteten Layer:

  • Das Tool “vmware-mount” produziert vor dem automatischen Mounten auf ein Zielverzeichnis aus den verstreuten Dateien des vmdk-Images zunächst ein zusammenhängendes “flat”- oder “raw”-File. Die darin beherbergten Partitionen/Filesysteme können wir dabei zur Not auch selbst mit fdisk/parted erkennen und als Loop-Devices mounten. Dabei sind Offset-Angaben zu beachten.
  • Das Tool “qemu-nbd” interpretiert komplexe vmdk-Images ebenfalls korrekt und bietet dem User über ein Kernelmodul einen Block-Layer an: das Disk-Image wird als Ganzes als Block-Device angeboten. Zudem werden enthaltene Filesysteme automatisch erkannt und ebenfalls als Block-Devices angeboten, wenn das Modul entsprechend parametriert wurde. Die im Block-Device der gesamten Disk enthaltenen Filesysteme können alternativ aber auch über Loop-Devices angesprochen werden.

Wir hatten zudem erkannt, dass man beim Einsatz der bisher besprochenen Tools bzgl. der resultierenden Zugriffsrechte aufpassen muss:

Ein automatisches Mounten mit vmware-mount geht mit Zugriffsrechten viel zu freizügig um. Eigene Mount-Befehle sind dagegen mit entsprechenden Optionen zu berechtigten Usern und Zugriffsmasken zu versehen – soweit möglich.

Wir stellen nun ein Tool vor, dass Sicherheitsaspekte beim Mounten von Disk-Images auf Hosts von Haus aus noch etwas ernster nimmt und FUSE nutzt, um Filesysteme von Disk-Image-Dateien unter Linux in handlicher Weise bereit zu stellen: guestmount.

Flankierend betrachten wir in diesem Artikel zudem zwei Tools, die es einem erlauben, die Snapshot- und Extent-Verteilung eines vmdk-Images sowie die enthaltenen Filesysteme vorab auch ohne Mount-Prozess zu ermitteln: qemu-img und virt-filesystems. Für den Einstieg in forensische Arbeiten mit unbekannten, komplexen vmdk-Images sind diese Kommandos zusammen mit Zeitstempelinformationen durchaus wertvoll.

Vorsicht bei Experimenten

Auch im Falle von “guestmount” gilt: Konkurrierende Schreibzugriffe auf das Disk-Image sind zu vermeiden. Das bedeutet, dass die virtuelle (VMware-, QEMU-, Virtualbox-) Maschine, die das vmdk-Image normalerweise als Disk nutzt, abgeschaltet sein muss. Zur Sicherheit Kopien der Disk-Images anlegen und ggf. nur “read only” mounten.

Notwendige Pakete

“guestmount” nutzt die libguestfs-Bibliothek. Das Kommando gehört zu einem ganzen Set von Tools, die seit 2009 für Virtualisierung (im Besonderen mit QEMU) entwickelt und optimiert wurden. Siehe hierzu die ganz unten angegebenen Links. Unter Opensuse benötigt man für “libguestfs” die Pakete libguestfs0, guestfs-tools,
guestfs-data und ggf. perl-Sys-Guestfs. Installieren sollte man in jedem Fall auch “qemu-tools“.

Unter Debian/Kali gibt es ebenfalls eine ganze Reihe von Paketen (s. den Link unten); das Notwendigste wird aber im Zuge der Installation von “libguestfs-tools” bereitgestellt. Das zudem nützliche Paket “qemu-utils” hatten wir schon im letzten Artikel erwähnt.

Interessant ist (unter Opensuse) im Besonderen das Paket guestfs-data: Die Beschreibung dieses RPM-Pakets zeigt, dass es eine minimale virtuelle Maschine (nach dem Supermin-Muster) beinhaltet, die offenbar von libguestfs-Anwendungen verwendet wird – wie wir sehen werden, auch von “guestmount”.

Bevor man “guestmount” einzusetzt, lohnt es sich, zunächst ein paar Informationen über das vmdk-Image und enthaltene Filesysteme zu sammeln.

Beschaffen von Infos zu Snapshots, Extents in vmdk-Disk-Image

Ein wichtiges Tool, um sich Informationen zur Datei-Struktur (Snapshot- und Extent-Files) von Disk-Images für virtuelle Maschinen zu verschaffen, ist “qemu-img“. Ein Auszug aus der man-Seite besagt:

qemu-img allows you to create, convert and modify images offline. It can handle all image formats supported by QEMU. .... The following commands are supported: ....
info [--object objectdef] [--image-opts] [-f fmt] [--output=ofmt] [--backing-chain] filename
snapshot [--object objectdef] [--image-opts] [-q] [-l | -a snapshot | -c snapshot | -d snapshot] filename
	snapshot is the name of the snapshot to create, apply or delete
    	-l  lists all snapshots in the given image
info [-f fmt] [--output=ofmt] [--backing-chain] filename
           Give information about the disk image filename. Use it in particular to know the size reserved on disk which can be different from the displayed size. If VM snapshots are stored in the disk image, they are displayed too. The command can output in the format ofmt           which is either "human" or "json".

           If a disk image has a backing file chain, information about each disk image in the chain can be recursively enumerated by using the option "--backing-chain".

Ähnliche Informationen gibt uns auch “qemu-img -h”. Der Wiki-Link zu “Qemu/Images” unten bestätigt, dass “qemu-img” die vmdk-Formate 3,4 und 6 unterstützt.

Der Ausdruck “backing-chain” erinnert den aufmerksamen Leser natürlich sofort an die “Link-Kette” für vmdk-Snapshots, die wir im zweiten Artikel dieser Serie angesprochen hatten.
Wer meinen letzten Artikel gelesen hat, weiß, dass ich ein vmdk-Test-Image habe, das drei Snapshots aufweist und dessen Base-Disk-File in einem anderen Verzeichnis liegt als die Dateien zu den Snapshots. Damit wollen wir “qemu-img” mal testen. (Ich mache das nachfolgend als User root; erforderlich ist das bei hinreichenden Zugriffsrechten auf die Image-Dateien aber keinesfalls.)

mytux:/vmw/Win7Test # qemu-img info Win7_x64_ssdx-000003.vmdk
image: Win7_x64_ssdx-000003.vmdk
file format: vmdk
virtual size: 4.0G (4294967296 bytes)
disk size: 24M
cluster_size: 65536
backing file: Win7_x64_ssdx-000002.vmdk
Format specific information:
    cid: 4245824591
    parent cid: 1112365808
    create type: twoGbMaxExtentSparse
            virtual size: 4261412864
            filename: Win7_x64_ssdx-000003-s001.vmdk
            cluster size: 65536
            format: SPARSE
            virtual size: 33554432
            filename: Win7_x64_ssdx-000003-s002.vmdk
            cluster size: 65536
            format: SPARSE

Wir sehen hier offenbar den Beginn der Snapshot-Historie: Der dritte VMware-Snapshot “Win7_x64_ssdx-000003.vmdk”, der bislang offenbar nur geringe Veränderungen aufnehmen musste, setzt auf auf einem “backing file” auf: Win7_x64_ssdx-000002.vmdk. Wir sehen damit allerdings noch nicht die gesamte Snapshot-Historie (s.u.).

Dafür erkennen wir aber, dass der Inhalt pro Snapshot über 2 sparse Extents verteilt ist. Die zugehörige CID-Information ist – wie wir aus dem 2-ten Artikel der Serie wissen – im Deskriptor-File des Snapshots beinhaltet. Insgesamt gilt, dass “qemu-img” im Fall von vmdk_Images im Wesentlichen den Inhalt der Deskriptor-Dateien darstellt.

Übersicht über die gesamte Backing-Chain
Wollen wir die gesamte Backing-Chain – also im Fall von vmdk-Images die vollständige Snapshot-Historie – sehen, müssen wir beim Kommando zusätzlich eine Unteroption “- -backing-chain” angeben:

mytux:/vmw/Win7Test # qemu-img info --backing-chain Win7_x64_ssdx-000003.vmdk
image: Win7_x64_ssdx-000003.vmdk
file format: vmdk
virtual size: 4.0G (4294967296 bytes)
disk size: 24M
cluster_size: 65536
backing file: Win7_x64_ssdx-000002.vmdk
Format specific information:
    cid: 4245824591
    parent cid: 1112365808
    create type: twoGbMaxExtentSparse
            virtual size: 4261412864
            filename: Win7_x64_ssdx-000003-s001.vmdk
            cluster size: 65536
            format: SPARSE
            virtual size: 33554432
            filename: Win7_x64_ssdx-000003-s002.vmdk
            cluster size: 65536
            format: SPARSE

image: Win7_x64_ssdx-000002.vmdk
file format: vmdk
virtual size: 4.0G (4294967296 bytes)
disk size: 1.1M
cluster_size: 65536
backing file: Win7_x64_ssdx-000001.vmdk
Format specific information:
    cid: 1112365808
    parent cid: 3509963510
    create type: twoGbMaxExtentSparse
            virtual size: 4261412864
            filename: Win7_x64_ssdx-000002-s001.vmdk
            cluster size: 65536
            format: SPARSE
            virtual size: 33554432
            filename: Win7_x64_ssdx-000002-s002.vmdk
            cluster size: 65536
            format: SPARSE

image: Win7_x64_ssdx-000001.vmdk
file format: vmdk
virtual size: 4.0G (4294967296 bytes)
disk size: 1.0M
cluster_size: 65536
backing file: /vmw/Win7/Win7_x64_ssdx.vmdk
Format specific information:
    cid: 3509963510
    parent cid: 3060125035
    create type: twoGbMaxExtentSparse
            virtual size: 4261412864
            filename: Win7_x64_ssdx-000001-s001.vmdk
            cluster size: 65536
            format: SPARSE
            virtual size: 33554432
            filename: Win7_x64_ssdx-000001-s002.vmdk
            cluster size: 65536
            format: SPARSE

image: /vmw/Win7/Win7_x64_ssdx.vmdk
file format: vmdk
virtual size: 4.0G (4294967296 bytes)
disk size: 2.2G
cluster_size: 65536
Format specific information:
    cid: 3060125035
    parent cid: 4294967295
    create type: twoGbMaxExtentSparse
            virtual size: 4261412864
            filename: /vmw_win7/Win7_x64_ssdx-s001.vmdk
            cluster size: 65536
            format: SPARSE
            virtual size: 33554432
            filename: /vmw_win7/Win7_x64_ssdx-s002.vmdk
            cluster size: 65536
            format: SPARSE
mytux:/vmw/Win7Test #   

“qemu-img” stellt uns eine über mehrere Filesystem-Orte verteilte Snapshot- und Extent-Zusammensetzung eines vmd-Images konsolidiert dar. Sprich: Durch die Option “- – backing-chain” werden alle Deskriptor-Dateien zu allen
Snapshots ausgelesen und in der richtigen Reihenfolge ausgegeben. Das ist zumindest im Falle mehrerer Disks und vieler Snapshots recht nützlich, zumal wenn unterschiedliche Disks eines VMware-Gastes sehr unterschiedliche Snapshot-Historien aufweisen sollten. Was einem in der Praxis durchaus unter die Finger kommt.

Leider muss der Linux-User aber von vornherein wissen, in welchem Verzeichnis man den jüngsten Snapshot (mit der höchsten Nummer im Namenszusatz) und die zugehörige Deskriptor-Datei findet. Die Verlinkung der vmdk-Snapshot-Chain erfolgt nur nach unten in Richtung Base-File – also einseitig.

Die im “type twoGbMaxExtentSparse” angegebenen 2GB für die Extends muss man unter aktuellen Linux-Systemen nicht zu ernst nehmen; faktisch operiert z.B. die VMware WS 14 mit wachsenden 4 GB Extents.


Da Snapshots in vmdk-Images über eine Backing-Chain (im VMware-Sprech: eine Link-Chain) realisiert werden, liefert uns das Kommando “qemu-img snapshot -l” keine passende Informationen; die Snapshots sind anders als etwa in qcow2-Disks nicht intrinsischer Teil des/der primären Image-Files.

mytux:/vmw/Win7Test # qemu-img snapshot -l  Win7_x64_ssdx-000003.vmdk
mytux:/vmw/Win7Test # 

Beschaffen von Informationen zu Filesystemen in einem vmdk-Disk-Image

Das obige Kommando hat uns noch nicht gezeigt, welche Partitionen/Filesysteme in der Disk aktuell beheimatet sind. Diese Information benötigen wir aber für die Anwendung von “guestmount”. Hier hilft die “libguestfs” mit dem Tool “virt-filesystems” weiter:

mytux:/vmw/Win7Test # virt-filesystems -a Win7_x64_ssdx-000003.vmdk -l
Name       Type        VFS   Label   Size        Parent
/dev/sda1  filesystem  ntfs  Volume  2718957568  -
/dev/sda2  filesystem  ntfs  Volume  1572864000  -

oder – für die zusätzliche Ausgabe von Partitionen:

mytux:/vmw/Win7Test # virt-filesystems -a Win7_x64_ssdx-000003.vmdk --all --long --uuid -h
Name      Type       VFS  Label  MBR Size Parent   UUID
/dev/sda1 filesystem ntfs Volume -   2.5G -        00E60BCAE60BBF42
/dev/sda2 filesystem ntfs Volume -   1.5G -        42A048ACA048A7ED
/dev/sda1 partition  -    -      07  2.5G /dev/sda -
/dev/sda2 partition  -    -      07  1.5G /dev/sda -
/dev/sda  device     -    -      -   4.0G -        -

Gut, nicht wahr?

Die Bezeichnungen “/dev/sda1”, “/dev/sda2” haben nichts mit evtl. existierenden, gleichnamigen Devices des aktuellen Hosts zu tun. Die Bezeichnungen beziehen sich ausschließlich auf interne Partitionen des Disk-Images.

Zu weiteren Optionen, wie etwa “–extra” für die Anzeige weiterer nicht mountbarer Filesysteme, siehe die man-page zum Kommando.

guestmount – bequemes Mounten vorhandener vmdk-Filesysteme

Mit dem obigen Wissen ausgestattet, können wir nun endlich guestmount einsetzen. Die Kommandostruktur ist für den Normalfall recht einfach

guestmount -a img-file -m /dev/sdax [–ro] mount-point-im-Linux-host

Wollen wir also in unserem Beispiel das zweite Filesystem mounten, so ist Folgendes anzugeben:

mytux:/vmw/Win7Test # guestmount -a Win7_x64_ssdx-000003.vmdk  -m /dev/sda2  --ro /mnt3 
mytux:/vmw/Win7Test # la /mnt3/
$RECYCLE.BIN/                           System Volume Information/
Cosmological_Voids/                     mysql-installer-community-
Muflons/                                ufos/
mytux:/vmw/Win7Test # la /mnt3/ufos/
total 5
drwxrwxrwx 1 root root    0 Mar 31 15:26 .
drwxrwxrwx 1 root root 4096 Mar 28 20:25 ..
-rwxrwxrwx 1 root root   18 
Mar 31 15:26 ufo.txt
-rwxrwxrwx 1 root root    0 Mar 31 14:02 xufos
mytux:/vmw/Win7Test #
mytux:/vmw/Win7Test # guestunmount  /mnt3 
mytux:/vmw/Win7Test # 


  • Zum Entfernen eines Mounts muss man das Kommand “guestunmount” verwenden.
  • Die Option “–ro” sorgt dafür, dass “read-only” gemountet wird.

guestmount – Möglichkeit zum gestaffelten Mounten

Es gibt weitere Optionen und Einsatzmöglichkeiten für “guestmount”, die man der man-Seite entnehmen kann. Die anderen Möglichkeiten sind aber eher für Linux/Unix-Filesysteme im vmdk-Image geeignet. Auf eine Möglichkeit – nämlich die eines geschachtelten Mounts in einem Schritt – möchte ich aber doch hinweisen.

Eines meiner mit VMware virtualisierten Windows 7-Testsysteme weist ein (freies) Verzeichnis “mounts/mnt2” auf. Der aktuelle Snapshot des Hauptsystems mit dem Win7-OS heißt “Win7_x64-cl1-000011.vmdk”. Dann kann man etwa Folgendes machen:

mytux:/vmw/Win7Test # guestmount -a Win7_x64-cl1-000005.vmdk -m /dev/sda1 -a Win7_x64_ssdx-000003.vmdk  -m /dev/sdb2:/mounts/mnt2  --ro /mnt2 
mytux:/vmw/Win7Test # la /mnt2/
total 4194272
drwxrwxrwx  1 root root          0 Jan 25  2014 $Recycle.Bin
drwxrwxrwx  1 root root      12288 Mar 20 18:05 .
drwxr-xr-x 39 root root       4096 Mar 28 17:02 ..
-rwxrwxrwx  1 root root       8192 Aug 23  2012 BOOTSECT.BAK
drwxrwxrwx  1 root root       4096 Sep 23  2016 Boot
lrwxrwxrwx  2 root root         60 Jul 14  2009 Documents and Settings -> /sysroot/Users
lrwxrwxrwx  2 root root         60 Aug 23  2012 Dokumente und Einstellungen -> /sysroot/Users
drwxrwxrwx  1 root root       4096 Jan 25  2014 Users
drwxrwxrwx  1 root root      24576 Apr  8 11:43 Windows
-rwxrwxrwx  1 root root 4294434816 Apr  8 11:41 pagefile.sys
drwxrwxrwx  1 root root       4096 Mar 27 19:37 mounts

mytux:/vmw/Win7Test # la /mnt2/mounts/mnt2/ufos/
total 5
drwxrwxrwx 1 root root    0 Mar 31 15:26 .
drwxrwxrwx 1 root root 4096 Mar 28 20:25 ..
-rwxrwxrwx 1 root root   18 Mar 31 15:26 ufo.txt
-rwxrwxrwx 1 root root    0 Mar 31 14:02 xufos

mytux:/vmw/Win7Test # la /mnt2/mounts
total 28
drwxrwxrwx 1 root root  4096 Mar 27 19:37 .
drwxrwxrwx 1 root root 12288 Mar 20 18:05 ..
drwxrwxrwx 1 root root     0 Mar 22 10:30 mnt
drwxrwxrwx 1 root root  4096 Mar 28 20:25 mnt2
lrwxrwxrwx 1 root root   216 Mar 27 19:21 mnt3 -> /sysroot/.NTFS-3G/Volume{c5......}
lrwxrwxrwx 1 root root   216 Mar 27 19:37 mnt4 -> /sysroot/.NTFS-3G/Volume{a4......}

Nett, nicht wahr? Man beachte, dass die Partitionen des zweiten mit der Option “-a” bereitgestellten Images mit “/dev/sdbx” bezeichnet werden. Einige Informationen wurden im obigen Auszug mit “….” ersetzt.

Die Frage ist halt, in wieweit ein solcher geschachtelter Mount mit Windows-Systemen Sinn macht. Man könnte einwenden, dass auch unter Windows Disks in den Verzeichnisbaum gemountet werden können. Stimmt auch – nur wird ein solcher Mount viel umständlicher realisiert als unter Linux. Im obigen Beispiel zeigen die letzten Zeilen gerade solche belegten Mount-Punkte. Die dortigen Windows-Verweise führen aber ohne gestartetes System ins Nirwana. So funktioniert Folgendes leider nicht:

mytux:/vmw/Win7Test #  guestmount -a Win7_x64-cl1-000005.vmdk -m /dev/sda1 -a Win7_x64_ssdx-000003.vmdk  -m /dev/sdb2:/mounts/mnt4  --ro /mnt2 
libguestfs: error: mount_options: mount: /mounts/mnt4: No such file or directory
guestmount: '/dev/sdb2' could not be mounted.
guestmount: Did you mean to mount one of these filesystems?
guestmount:     /dev/sda1 (ntfs)
guestmount:     /dev/sdb1 (ntfs)
guestmount:     /dev/sdb2 (ntfs)

Man kann daher – auch wennn man schon weiß, wie
bestimmte NTFS-Partitionen in das Windows-Hauptlaufwerk gemountet werden – diese Verhältnisse unter Linux nicht direkt nachstellen.

Auf ähnliche Einschränkungen stößt man bzgl. der Guestmount-Option “-i” für vmdk-Images. Auch eine automatische Aufdröselung von Mount-Punkten funktioniert mit NTFS-Filesystemen nicht. Das ist aber nicht so schlimm; Forensiker können die wahre Struktur eine Windows-Maschine über die Registry (in Subverzeichnissen von Windows/System32/config) und Infos in weiteren Verzeichnissen auslesen.

guestmount – Sicherheit über Einsatz einer minimalen virtuellen QEMU-Maschine

Der Leser erinnert sich sicher an die mahnenden Worte von D.P.Berrange in
bzgl. der Risiken beim Mounten von Disk-Images virtualisierter Gastsysteme auf einem Linux-Host. Weitere Hinweise auf solche Risiken liefern die Entwickler von libguestfs unter folgendem Link:

Um evtl. Problemen mit manipulierten Disk-Images und ihren Filesystemen vorzubeugen, operiert “libguestfs” mit einer virtuellen QEMU-Maschine im Hintergrund. Ich zitiere aus dem Text des eben genannten Links:

“We run a Linux kernel inside a qemu virtual machine, usually running as a non-root user. The attacker would need to write a filesystem which first exploited the kernel, and then exploited either qemu virtualization (eg. a faulty qemu driver) or the libguestfs protocol, and finally to be as serious as the host kernel exploit it would need to escalate its privileges to root. Additionally if you use the libvirt back end and SELinux, sVirt is used to confine the qemu process. This multi-step escalation, performed by a static piece of data, is thought to be extremely hard to do, although we never say ‘never’ about security issues.”

Hervorhebung durch mich. Leute, dieser Ansatz gefällt mir! Dennoch funktioniert er auf einem Opensuse-System ohne SE-Linux, aber mit AppArmor, leider nicht vollständig (s.u.).

Können wir die virtuelle QEMU-Maschine (die übrigens von der Supermin-Gattung ist) sehen? Ja das geht; z.B. als unpriviligierter User “myself”:

myself:/vmw/ssdx> ps aux | grep qemu
myself      18986  0.0  0.0  10564  1640 pts/8    S+   12:22   0:00 grep --color=auto qemu
myself:/vmw/ssdx> guestmount -a Win7_x64_ssdx.vmdk  -m /dev/sda2  --ro /mnt/vmdk                                                        
myself:/vmw/ssdx> ps aux | grep qemu
myself      19002 19.8  0.3 1534676 247408 pts/8  Sl   12:22   0:00 /usr/bin/qemu-system-x86_64 -global virtio-blk-pci.scsi=off -nodefconfig -enable-fips -nodefaults -display none -machine accel=kvm:tcg -cpu host -m 500 -no-reboot -rtc driftfix=slew -no-hpet -global kvm-pit.lost_tick_policy=discard -kernel /var/tmp/.guestfs-1553/appliance.d/kernel -initrd /var/tmp/.guestfs-1553/appliance.d/initrd -device virtio-scsi-pci,id=scsi -drive file=/tmp/libguestfsCrlFc9/overlay1,cache=unsafe,format=qcow2,id=hd0,if=none -device scsi-hd,drive=hd0 -drive file=/var/tmp/.guestfs-1553/appliance.d/root,snapshot=on,id=appliance,cache=unsafe,if=none -device scsi-hd,drive=appliance -device virtio-serial-pci -serial stdio -device sga -chardev socket,path=/tmp/libguestfsCrlFc9/guestfsd.sock,id=channel0 -device virtserialport,chardev=channel0, -append panic=1 console=ttyS0 udevtimeout=6000 udev.event-timeout=6000 no_timer_check acpi=off printk.time=1 cgroup_disable=memory root=/dev/sdb selinux=0 TERM=xterm-256color                                                                                                                                      
myself      19021  0.0  0.0  10564  1648 pts/8    S+   12:22   0:00 grep --color=auto qemu
myself:/vmw/ssdx> guestunmount /
myself:/vmw/ssdx> ps aux | grep qemu
myself      19047  0.0  0.0  10564  1652 pts/8    S+   12:22   0:00 grep --color=auto qemu

Man beachte die leider erfolgte Deaktivierung des Security Models durch den Parameter “selinux=0”; auf meinem Opensuse-System läuft AppArmor.

Immerhin: Es ist gut, dass eine virtuelle Maschine bei der Ausführung der guestmount- oder generell von libguestfs-Befehle zwischengeschaltet wird. Wie genau die Übergänge zwischen Fuse auf dem Linux-Host, dem Starten einer QEMU-Maschine, dem nachfolgenden Mount-Prozess innerhalb der QEMU-Machine (wiederum unter Einbeziehung von FUSE für das dortige Mounten des entdeckten Filesystems, z.B. NTFS) und dem Re-Export des schließlich emulierten Block-Devices auf den Host – genauer: auf den dortigen Mount-Point – funktioniert, muss uns als Anwender – Gott sei Dank – nicht interessieren. Aus dem Jahr 2009 stammt vom Erfinder folgende Darstellung der Prozess-Kette:

Linux VFS (in the host) -> fuse -> guestmount process -> libguestfs -> XDR protocol over a TCP socket -> host kernel -> QEMU’s SLIRP stack -> guest kernel -> guestfsd -> Linux VFS (in the guest) -> fuse -> mount-ntfs-3g -> Windows block device -> QEMU (emulating the block device) -> host kernel -> real block device


Teile davon dürften heute wohl noch stimmen. Habe aber keine genaue Ahnung … 🙂 .

Ein paar Infos zur virtuellen libguestfs-QEMU-Maschine

Man kann das Starten der virtuellen Maschine auch an “libvirtd” deligieren. Das hat den Vorteil, dass man mittels per virsh-Kommandos ein paar Informationen über die virtuelle QEMU-Maschine ermitteln kann. Notwendig zum Involvieren von “libvirt” ist das Setzen einer Umgebungsvariablen für die Shell des unpriviligierten Users:


Führen wir dann wieder “guestmount” aus, sehen wir, dass der Aufruf der virtuellen Maschine mit anderer Parametersetzung erfolgt:

myself:/vmw/ssdx> export LIBGUESTFS_ATTACH_METHOD=libvirt
myself:/vmw/ssdx> guestmount -a Win7_x64_ssdx.vmdk  -m /dev/sda2  --ro /mnt/vmdk
myself:/vmw/ssdx> ps aux | grep qemu
myself      13201  5.2  0.3 1927592 261572 ?      Sl   17:20   0:01 /usr/bin/qemu-system-x86_64 -machine accel=kvm -name guest=guestfs-7pup8sjqcmvakaoz,debug-threads=on -S -object secret,id=masterKey0,format=raw,file=/home/myself/.config/libvirt/qemu/lib/domain-1-guestfs-7pup8sjqcmva/master-key.aes -machine pc-i440fx-2.9,accel=kvm,usb=off,dump-guest-core=off -cpu host -m 500 -realtime mlock=off -smp 1,sockets=1,cores=1,threads=1 -uuid 61273dde-6a1c-4c0a-be8d-ae06494041aa -display none -no-user-config -nodefaults -device sga -chardev socket,id=charmonitor,path=/home/rmo/.config/libvirt/qemu/lib/domain-1-guestfs-7pup8sjqcmva/monitor.sock,server,nowait -mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc,driftfix=slew -global kvm-pit.lost_tick_policy=delay -no-hpet -no-reboot -no-acpi -boot strict=on -kernel /var/tmp/.guestfs-1553/appliance.d/kernel -initrd /var/tmp/.guestfs-1553/appliance.d/initrd -append panic=1 console=ttyS0 udevtimeout=6000 udev.event-timeout=6000 no_timer_check acpi=off printk.time=1 cgroup_disable=memory root=/dev/sdb selinux=0 TERM=xterm-256color -device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 -device virtio-scsi-pci,id=scsi0,bus=pci.0,addr=0x2 -device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x3 -drive file=/tmp/libguestfsi5ApZX/overlay1,format=qcow2,if=none,id=drive-scsi0-0-0-0,cache=unsafe -device scsi-hd,bus=scsi0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0-0-0-0,id=scsi0-0-0-0,bootindex=1 -drive 
file=/tmp/libguestfsi5ApZX/overlay2,format=qcow2,if=none,id=drive-scsi0-0-1-0,cache=unsafe -device scsi-hd,bus=scsi0.0,channel=0,scsi-id=1,lun=0,drive=drive-scsi0-0-1-0,id=scsi0-0-1-0 -chardev socket,id=charserial0,path=/tmp/libguestfsi5ApZX/console.sock -device isa-serial,chardev=charserial0,id=serial0 -chardev socket,id=charchannel0,path=/tmp/libguestfsi5ApZX/guestfsd.sock -device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0, -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4 -msg timestamp=on
myself      13256  0.0  0.0  10564  1612 pts/5    S+   17:20   0:00 grep --color=auto qemu

virsh zeigt uns auch Devices der virtuellen Maschine an; leider aber nicht Details:

myself:/vmw/ssdx> virsh
Willkommen bei virsh, dem interaktiven Virtualisierungsterminal.

Tippen Sie:  'help' für eine Hilfe zu den Befehlen
       'quit' zum Beenden

virsh # list
 Id    Name                           Status
 1     guestfs-7pup8sjqcmvakaoz       laufend

virsh # domblklist guestfs-7pup8sjqcmvakaoz
Ziel       Quelle
sda        /tmp/libguestfsi5ApZX/overlay1
sdb        /tmp/libguestfsi5ApZX/overlay2

virsh # domblkinfo guestfs-7pup8sjqcmvakaoz sda
Kapazität:     4294967296
Zuordnung:      200704
Physisch:       196672

virsh # domblkinfo guestfs-7pup8sjqcmvakaoz sdb
Kapazität:     4294967296
Zuordnung:      1904640
Physisch:       1966080

Man kann auch noch rausbekommen, dass unser vmdk.file innerhalb der virtuellen Maschine mit /dev/sda assoziiert ist:

virsh # dumpxml guestfs-7pup8sjqcmvakaoz
<domain type='kvm' id='1' xmlns:qemu=''>
  <memory unit='KiB'>512000</memory>
  <currentMemory unit='KiB'>512000</currentMemory>
  <vcpu placement='static'>1</vcpu>
    <type arch='x86_64' machine='pc-i440fx-2.9'>hvm</type>
    <cmdline>panic=1 console=ttyS0 udevtimeout=6000 udev.event-timeout=6000 no_timer_check acpi=off printk.time=1 cgroup_disable=memory root=/dev/sdb selinux=0 TERM=xterm-256color</cmdline>
    <boot dev='hd'/>
    <bios useserial='yes'/>
  <cpu mode='host-passthrough' check='none'/>
  <clock offset='utc'>
    <timer name='rtc' tickpolicy='catchup'/>
    <timer name='pit' tickpolicy='delay'/>
    <timer name='hpet' present='no'/>
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2' cache='unsafe'/>
      <source file='/tmp/libguestfsi5ApZX/overlay1'/>
      <backingStore type='file' index='1'>
        <format type='raw'/>
        <source file='/vmw_win7/ssdx/Win7_x64_ssdx.vmdk'/>
      <target dev='sda' bus='scsi'/>
      <alias name='scsi0-0-0-0'/>
      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
    <disk type='file' device='disk'>
      <driver name='
qemu' type='qcow2' cache='unsafe'/>
      <source file='/tmp/libguestfsi5ApZX/overlay2'/>
      <backingStore type='file' index='1'>
        <format type='raw'/>
        <source file='/var/tmp/.guestfs-1004/appliance.d/root'/>
      <target dev='sdb' bus='scsi'/>
      <alias name='scsi0-0-1-0'/>
      <address type='drive' controller='0' bus='0' target='1' unit='0'/>
    <controller type='scsi' index='0' model='virtio-scsi'>
      <alias name='scsi0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
    <controller type='usb' index='0' model='piix3-uhci'>
      <alias name='usb'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
    <controller type='pci' index='0' model='pci-root'>
      <alias name='pci.0'/>
    <controller type='virtio-serial' index='0'>
      <alias name='virtio-serial0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    <serial type='unix'>
      <source mode='connect' path='/tmp/libguestfsi5ApZX/console.sock'/>
      <target port='0'/>
      <alias name='serial0'/>
    <console type='unix'>
      <source mode='connect' path='/tmp/libguestfsi5ApZX/console.sock'/>
      <target type='serial' port='0'/>
      <alias name='serial0'/>
    <channel type='unix'>
      <source mode='connect' path='/tmp/libguestfsi5ApZX/guestfsd.sock'/>
      <target type='virtio' name='' state='connected'/>
      <alias name='channel0'/>
      <address type='virtio-serial' controller='0' bus='0' port='1'/>
    <input type='mouse' bus='ps2'>
      <alias name='input0'/>
    <input type='keyboard' bus='ps2'>
      <alias name='input1'/>
    <memballoon model='virtio'>
      <alias name='balloon0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
    <qemu:env name='TMPDIR' value='/var/tmp'/>

Man beachte den zweiten Eintrag unter <devices> !

Das war es dann aber auch schon;

virsh # domfsinfo
Fehler: Befehl 'domfsinfo' erfordert <domain> Option
virsh # domfsinfo guestfs-7pup8sjqcmvakaoz
Fehler: Unable to get filesystem information
Fehler: argument unsupported: QEMU guest agent is not configured

Wie der programmierte Fuse-Prozess auf dem Host das QEMU-Gastsystem und das dort benutzten /dev/sda auf den mountpoint auf dem Host bringt, lässt sich mit einfachen Systemtools niocht weiter analysieren. Das /dev/fuse auf /mnt/vmdk gemountet wird, ist dabei eine wenig aussagekräftige Binsenweisheit:

myself:/vmw/ssdx> mount | grep fuse
fusectl on /sys/fs/fuse/connections type fusectl (rw,relatime)
vmware-vmblock on /run/vmblock-fuse type fuse.vmware-vmblock (rw,nosuid,nodev,relatime,user_id=0,group_id=0,default_permissions,allow_other)
gvfsd-fuse on /run/user/1553/gvfs type fuse.gvfsd-fuse (rw,nosuid,nodev,relatime,user_id=1553,group_id=100)
/dev/fuse on /mnt/vmdk type fuse (rw,nosuid,nodev,relatime,user_id=1553,group_id=100)
vmw/ssdx> la /sys/fs/fuse/connections/47
insgesamt 0
dr-x------ 2 myself  users 0 13. Apr 17:20 .
drwxr-xr-x 5 root root  0 13. Apr 09:15 ..
--w------- 1 myself  users 0 13. Apr 17:20 abort
-rw------- 1 myself  users 0 13. Apr 17:20 congestion_threshold
-rw------- 1 myself  users 0 13. Apr 17:20 max_background
-r-------- 1 myself  users 0 13. Apr 17:20 waiting

Sicherheit – Zugriff durch andere User?

Die Informationsseiten zu “guestmount” versprechen Folgendes:

Other users cannot see the filesystem by default. .. If you mount a filesystem as one user (eg. root), then other users will not be able to see it by default. The fix is to add the FUSE allow_other option when mounting:
sudo guestmount […] -o allow_other /mnt
and to enable this option in /etc/fuse.conf.

Eine nette Frage ist deshalb: Wie sicher ist denn der Zugang zu dem gemounteten Filesystem? Die angezeigten Rechte deuten eigentlich an, dass jeder zugreifen darf:

myself:/vmw/ssdx> la /mnt/vmdk
insgesamt 196128
drwxrwxrwx 1 root root      4096 28. Mär 19:53 .
drwxr-xr-x 5 root root      4096  8. Apr 11:14 ..
drwxrwxrwx 1 root root      4096 28. Mär 09:53 Cosmological_Voids
-rwxrwxrwx 2 root root 200822784  4. Nov 2013  mysql-installer-community-
drwxrwxrwx 1 root root         0 28. Mär 09:52 $RECYCLE.BIN
drwxrwxrwx 1 root root         0 28. Mär 09:51 System Volume Information
drwxrwxrwx 1 root root         0 28. Mär 19:53 ufos

Das täuscht aber; den selbst als User “root” erlebt man Folgendes:

mytux:~ # la /mnt/vmdk
ls: cannot access '/mnt/vmdk': Permission denied
mytux:~ # la /mnt/
ls: cannot access '/mnt/vmdk': Permission denied
total 16
drwxr-xr-x  5 root root 4096 Apr  8 11:14 .
drwxr-xr-x 39 root root 4096 Mar 28 17:02 ..
drwxr-xr-x  3 root root 4096 Mar 20  2017 bups
drwxr-xr-x  2 root root 4096 Apr  4  2017 tux
d?????????  ? ?    ?       ?            ? vmdk

Mit dieser Rechtesetzung kann nicht mal der User “root” was anfangen!


guestmount immer als unpriviligierter User ausführen!

(Auch wenn ich das selbst in den ersten Beispielen dieses Artikels selbst nicht gemacht habe.)

Apparmor als Security-Modell für die libguestfs-QEMU-Maschine wird leider (noch) ignoriert!

Die Tatsache, dass die libguestfs-Etwickler selbst darauf hinweisen, dass für die virtuelle libguestfs-Maschine sVirt und Sicherheitsregeln von SE-Linux/Apparmor zum Zuge kommen, weist uns auf 2 Dinge hin:

  • Wir sollten “guestmount” nicht als root ausführen, wenn das nicht zwingend nötig ist. Die Rechte an den vmdk-Files ändern wir ggf. entsprechend ab.
  • Wir sollten auf dem Linux-System, das wir für unsere Arbeiten verwenden, die Sicherheitseinstellungen für SELinux oder Apparmor prüfen!

Man kann “libvirt” auf einem Opensuse-System, auf dem Aparmor und nicht SE-Linux eingestzt wird, wie folgt konfigurieren: In der Datei “/etc/libvirt/qemu.conf” setzt man:

security_driver = “apparmor”
security_default_confined = 1
security_require_confined = 1

Zur Bedeutung dieser Parameter siehe die Erläuterungen im File selbst. Für normale virtuelle Maschinene funktioniert das auch; als Beispiel mag eine virtuelle Debian-Maschine dienen:

mytux:~ # ps aux | grep debian9
qemu     15096 14.2  0.2 9410692 193460 ?      Dl   17:51   0:08 /usr/bin/qemu-system-x86_64 -machine accel=kvm -name guest=debian9,debug-threads=on -S -object secret,id=masterKey0,format=raw,file=/var/lib/libvirt/qemu/domain-1-debian9/master-key.aes ...
mytux~ # virsh 
Welcome to virsh, the virtualization interactive terminal.

 'help' for help with commands
       'quit' to quit

virsh # list
 Id    Name                           State
 1     debian9                        running

virsh # dominfo debian9
Id:             1
Name:           debian9
UUID:           789498d2-e025-4f8e-b255-5a3ac0f9c965
OS Type:        hvm
State:          running
CPU(s):         3
CPU time:       16.4s
Max memory:     8388608 KiB
Used memory:    8388608 KiB
Persistent:     yes
Autostart:      disable
Managed save:   no
Security model: apparmor
Security DOI:   0
Security label: libvirt-789498d2-e025-4f8e-b255-5a3ac0f9c965 (enforcing)
virsh # 

Man beachte den korrekten Wert “apparmor” für das “Security model”.

[Off topic: Man erkennt übrigens, dass libvirt die QEMU-Maschine dem user qemu zuordnet und selbst mit root-Rechten operiert, selbst wenn man die virtuelle Machine über virt-manager als unprivilegierter User startet.]

Aber für unsere vom User “myself” per guestmount gestartet Maschine liefert virsh:

myself:/vmw/ssdx> virsh
virsh # dominfo guestfs-7pup8sjqcmvakaoz
Id:             1
Name:           guestfs-7pup8sjqcmvakaoz
UUID:           61273dde-6a1c-4c0a-be8d-ae06494041aa
OS Typ:         hvm
Status:         laufend
CPU(s):         1
CPU-Zeit:       1,3s
Max Speicher:   512000 KiB
Verwendeter Speicher: 512000 KiB
Bleibend:       nein
Automatischer Start: deaktiviert
Verwaltete Sicherung: nein
Sicherheits-Modell: none
Sicherheits-DOI: 0

Schade, kein Sicherheitsmodell! Apparmor wird hier ignoriert, obwohl wir den Start der libguestfs-QEMU-Maschine an libvirtd deligiert hatten! Perfekt ist das libguestfs/guestmount an dieser Stelle also (noch!) nicht …

Eine entsprechende Anfrage bei den libguestfs-Entwicklern habe ich übrigens gestartet. Siehe:

Konvertierung von vmdk-Disk-Images inkl. aller Snapshops und Extents in ein “raw-File” mit Hilfe von qemu-img

Wir kommen am Ende dieses Artikels nochmal auf das eingangs schon betrachtete Tool “qemu-img” zurück: Man kann “qemu-img” auch dazu verwenden, ein vmdk-Disk-Image in genau ein zusammenhängendes “raw-File” umzuwandeln. Das belegt dann allerdings den Plattenplatz, den die Extents bereits einnehmen.

mytux:/vmw/Win7Test # qemu-img convert -f vmdk -O raw -S 4k Win7_x64_ssdx-000003.vmdk image_ssdx.raw
mytux:/vmw/Win7Test # la -h | grep image
-rw-r--r-- 1 root root  4.0G Apr  7 14:46 image_ssdx.raw
mytux:/vmw/Win7Test # du -h image_ssdx.raw 
2.2G    image_ssdx.raw

mytux:/vmw/Win7Test # fdisk -l image_ssdx.raw
Disk image_ssdx.raw: 4 GiB, 4294967296 bytes, 8388608 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x0efb9e3e

Device          Boot   Start     End Sectors  Size Id Type
image_ssdx.raw1         2048 5312511 5310464  2.5G  7 HPFS/NTFS/exFAT
image_ssdx.raw2      5312512 8384511 3072000  1.5G  7 HPFS/NTFS/exFAT
mytux:/vmw/Win7Test # 
mytux:/vmw/Win7Test # losetup -o 2720006144 /dev/loop2 image_ssdx.raw 
mytux:/vmw/Win7Test # mount /dev/loop2 /mnt2
mytux:/vmw/Win7Test # la /mnt2
total 196128
drwxrwxrwx  1 root root         0 Mar 28 09:52 $RECYCLE.BIN
drwxrwxrwx  1 root root      4096 Mar 28 20:25 .
drwxr-xr-x 39 root root      4096 Mar 28 17:02 ..
drwxrwxrwx  1 root root      4096 Mar 28 09:53 Cosmological_Voids
drwxrwxrwx  1 root root         0 Mar 28 20:26 Muflons
drwxrwxrwx  1 root root         0 Mar 28 09:51 System Volume Information
-rwxrwxrwx  2 root root 200822784 Nov  4  2013 mysql-installer-
drwxrwxrwx  1 root root         0 Mar 31 15:26 ufos
mytux:/vmw/Win7Test # umount /mnt2
mytux:/vmw/Win7Test # losetup -d /dev/loop2

Die Berechnung des Offsets für das “losetup”-Kommando hatten wir schon in den letzten Artikeln besprochen. Die letzten zwei Kommandos drehen alles wieder zurück. Natürlich wird man bei Bedarf beim Mounten noch Einschränkungen der Zugriffsrechte vornehmen; siehe auch hierzu den letzten Artikel.

Vertraut der am Inhalt von vmdk-Files Interessierte/Forensiker also nicht auf “guestmount” oder “vmware-mount”, kann er mit Hilfe von “qemu-img” zunächst immer ein raw-File erstellen, mit dem er dann nach Herzenslust herumwerkeln kann.


Im nächsten Artikel dieser Serie

Mounten eines vmdk-Laufwerks im Linux Host – IV – affuse, vdfuse

werfen wir einen kleinen (etwas entäuschenden) Blick auf “affuse” und “vdfuse”.


Infos zu libguestfs


Debian Packets
Deb-packets for libguestfs


Allgemeines questions 22327728 mounting-vmdk-disk-image