Skip to content

Recent Posts

Proxmox Complete Microsegmentation with OPNsense

Goal

The goal state for this setup is:

  • OPNsense acts as a core firewall and regulates access between all VMs.
  • All VMs share the same bridge interface to reduce setup needed for each VM.
  • VMs cannot spoof their IP address or MAC address to circumvent firewall controls.

pfSense will likely work with this setup as well, but was not tested.

Overview

To achieve the goal, we:

  • Create a bridge interface in Proxmox that all VMs (including the OPNsense VM) will share.
  • Using ebtables, block traffic on the bridge at Layer 2 unless to/from the OPNsense VM.
  • With Layer 2 traffic between the VMs blocked, there are no ARP replies for VM IP addresses. To solve this, we enable Proxy ARP in OPNsense.
  • Using Proxmox's built-in firewall, we enable the IP and MAC filter options to resolve IP and MAC spoofing.

0. Decide the VM subnet

This guide will assume 10.10.10.0/24 as the subnet for the VMs with 10.10.10.1 as the OPNsense gateway.

1. Enable Firewall Settings on the Datacenter

The firewall needs to be enabled at the Datacenter level and the VM level. Enabling the firewall on the node is not required.

  1. Navigate to Datacenter > Firewall > Options.
  2. Change Firewall to Yes.

2. Create the Proxmox Bridge Interface

Add the interface on your Proxmox node.

  1. Navigate to Your Node > System > Network.
  2. Click Create > Linux Bridge.
  3. Type your interface name. This documentation will use vmbr1.
  4. Leave all other fields as default (IP/CIDRs blank, VLAN aware off, no bridge ports).
  5. Click Create.

3. Add and configure the interface to OPNsense

This guide will not go into details on how to add the interface to OPNsense (I forgot exactly how I did it, and I don't feel like redoing it), however the key points are:

  • Add the interface as a LAN interface.
  • Do not enable the Proxmox Firewall on the OPNsense VM.
  • Do not specify a VLAN tag in Proxmox.

Important: Proxy ARP must be enabled on the interface in OPNsense. This is required as we are going to block Layer-2 traffic between the VMs, and so OPNsense must advertise its MAC address as owning all IPs in the subnet.

  1. Navigate to Interfaces > Virtual IPs > Settings.
  2. Click the + (Add) button.
  3. For Mode, select Proxy ARP.
  4. For Interface, select the added LAN interface.
  5. For Network / Address, input 10.10.10.0/24 (or your subnet).
  6. Click Save.

For testing purposes, a rule to allow pinging the gateway from all sources on the LAN interface was added.

4. Configure the Proxmox Bridge Interface

SSH into the Proxmox node to conduct some advanced configuration of the bridge interface.

Run brctl show vmbr1 to see the interfaces attached to the bridge (replace vmbr1 with your bridge). Example output:

root@yournode:~# brctl show vmbr1
bridge name     bridge id               STP enabled     interfaces
vmbr1           8000.624b81ab2fd5       no              tap101i1

Here we can see tap101i is the interface used by the OPNsense VM that is attached to the vmbr1 bridge.

Now we can configure the interface to only allow traffic from VMs to OPNsense and vice-versa using ebtables. No traffic allowed between other VMs.

  1. Run this command: nano /etc/network/interfaces
  2. Add post-up and post-down lines to the vmbr1 interface, such that the configuration looks like this (swap vmbr1 for your bridge and tap101i1 for your OPNsense VM interface):
    ...
    auto vmbr1
    iface vmbr1 inet static
            bridge-ports none
            bridge-stp off
            bridge-fd 0
            post-up   ebtables -A FORWARD --logical-in vmbr1 -o tap101i1 -j ACCEPT
            post-up   ebtables -A FORWARD -i tap101i1 --logical-out vmbr1 -j ACCEPT
            post-up   ebtables -A FORWARD --logical-in vmbr1 --logical-out vmbr1 -j DROP
            post-down ebtables -D FORWARD --logical-in vmbr1 -o tap101i1 -j ACCEPT
            post-down ebtables -D FORWARD -i tap101i1 --logical-out vmbr1 -j ACCEPT
            post-down ebtables -D FORWARD --logical-in vmbr1 --logical-out vmbr1 -j DROP
    #LAN Microsegmented
    ...
    
  3. Apply the network interface changes with this command: ifreload -a

5. Setup a VM

This guide will not go into details of the VM setup, except related specifically to networking. Key points inside the VM (or Cloud-Init) are:

  • Configure your VM's IP/CIDR to the desired IP and subnet (i.e. 10.10.10.3/24).
  • Configure your VM's gateway to the OPNsense VM's IP (i.e. 10.10.10.1).

In the Proxmox interface:

  1. Add vmbr1 (or your bridge) to your VM as a network device. Ensure the Firewall option is checked.
  2. Navigate to Your VM > Firewall > Options.
  3. Set Firewall to Yes.
  4. Set DHCP to No.
  5. Set MAC filter to Yes.
  6. Set IP filter to Yes.
  7. Set Input Policy to ACCEPT (input firewall rules will be configured in OPNsense).
  8. Set Output Policy to ACCEPT (output firewall rules will be configured in OPNsense).

In addition to these Firewall options, we need to make Proxmox aware of the VM's intended IP address so the IP filter setting will behave properly.

  1. Navigate to Your VM > Firewall > IPSet.
  2. Click Create.
  3. For Name, enter ipfilter-net0.
  4. Click OK.
  5. Click Add (top-right of interface).
  6. Enter the VM's IP address (i.e. 10.10.10.3).
  7. Reboot the VM.

Repeat this testing for a second VM to test inter-VM connectivity.

6. Testing

6.1 Inter-VM Connectivity

To test inter-VM connectivity:

  1. From one VM, attempt to ping the other VM (this should fail/timeout): ping 10.10.10.4
  2. In OPNsense interface, add a firewall rule that allows ICMP from 10.10.10.3 to 10.10.10.4.
  3. Attempt to ping the other VM again (this should succeed): ping 10.10.10.4

6.2. VM IP Spoofing

Testing IP-spoofing (on an Ubuntu VM):

# Attempt to ping other VM (should succeed)
ping 10.10.10.4

# Change IP address to one not defined in VM's IPSet
nano /etc/netplan/50-cloud-init.yaml
netplan apply

# Attempt to ping other VM (should fail)
ping 10.10.10.4

6.3. VM MAC Spoofing

Test MAC-spoofing (on an Ubuntu VM):

# Attempt to ping other VM (should succeed)
ping 10.10.10.4

# Change MAC address to one not defined on VM's interface.
# This can be done by adding a line to the interface's configuration.
#     match:
#         macaddress: 01:23:45:67:89:ab
# +   macaddress: de:de:de:de:de:de # added line, spoofed mac address
nano /net/netplan/50-cloud-init.yaml
netplan apply

# Attempt to ping other VM (should fail)
ping 10.10.10.4

In order to revert the spoofed changes, you may need to populate the original MAC address in both locations in the configuration, prior to restoring the original configuration:

match:
    macaddress: 01:23:45:67:89:ab
macaddress: 01:23:45:67:89:ab

Restore unspoofed MAC address:

netplan apply

Restore the original configuration:

match:
    macaddress: 01:23:45:67:89:ab
# no second macaddress line

Apply changes for the last time:

netplan apply

Done

Now you should have VM-level/complete microsegmentation setup. Enjoy the cloud-like control to your heart's content.

If you find any issues/comments with this setup, or a method to bypass the firewall controls, feel free to contact me.

AthackCTF 2024: egyptian-chess writeup

Category: misc, ppc (professional programming challenges)

Difficulty: Hard (1 solve)

Author: Hugo

Attachments: asd.py

This year, the rest of the Shell We Hack? team and I travelled to Montreal to compete in-person at AthackCTF 2024. The competition was difficult and fun, and after 23 hours we managed to secure 2nd place. Alongside this accomplishment, we were the only team to solve the egyptian-chess challenge. Here's how we did it.

First look

CyberSci Regionals 2023: Defence Challenges

This year at CyberSci Regionals, I competed along with the rest of the Shell We Hack? team. The organizers decided to introduce a new category - Defence. In this category, you are tasked with fixing vulnerabilities some given source code. This is very similar to what was seen at CyberSci Nationals 2023 (the summer before this competition).

There were a total of five challenges covering two services. The services were:

A user interface was provided, which allowed us to launch the attacks one-by-one. This gave us the ability to search logs to help determine where the vulnerability was.

Note: I do not remember the exact order of the challenges, so if you were a competitor, sorry :P

Working Away

DownUnderCTF 2023: baby ruby / real baby ruby writeups

Prompt (baby ruby):

How well do you know your Ruby?

The flag is at /chal/flag.

Author: hashkitten

nc 2023.ductf.dev 30028

Prompt (real baby ruby):

How well do you really know your Ruby?

The flag is at /chal/flag.

Author: hashkitten

nc 2023.ductf.dev 30031

Hint: ARGF is a stream designed for use in scripts that process files given as command-line arguments or passed in via STDIN.

Difficulty: Medium

Attachments: baby.rb, real-baby.rb

CyberSci Hardware Challenge

A copy of this writeup is written in the UNBCTF's writeups repository.

Difficulty: Medium/Hard

The objective of the challenge is to dump the firmware from the provided hardware badge and reverse engineer it. In theory this is quite easy, however it took quite some time to get familiar with the AVR architecture and instruction set.

Hints: If you're just starting out, ask Jeff Bezos for help. If you're near the end, ask Jeff Bezos for help.

Attachments: flash.hex, sram.hex, eeprom.hex

(these attachments were not provided, and had to be recovered as part of the challenge)

Solution: asd.py

The Badge

Front of hardware badge