Secure Design & Secure Coding Wie schaut sicherer Code aus?
René Pfeiffer, DeepSec In-Depth Security Conference
Linuxwochen Eisenstadt 2021, 24. April 2021
ls -l $(which whoami)
● René Pfeiffer
● Senior Sysadmin, Vortragender & Security Consultant
● Theoretische Physik
● Internet User seit 1992
● Config, Code, Crypto, Chaos
● DeepSec & DeepINTEL
Konferenzen W e
e
d u ,
,
, ,
Bild: τ Lepton Zerfall, Quelle https://commons.wikimedia.org/wiki/File:Feynman_diagram_of_decay_of_tau_lepton.svg
Software - Geschichte
● Algorithmen (Abu Dschaʿfar Muhammad ibn Musa Chwārizmī)
● Ada Lovelace – 19. Jahrhundert
● Digitalisierung – 1941 (Z3, Deutsche Luftwaffe)
● Creeper Test Virus – 1971 (DEC PDP-10, ARPANET)
● Reaper Test Cleaner (sucht & löscht Creeper Virus)
● Elk Cloner – 1982 (Macintosh, erster Computervirus)
Sicherheit
● Lange (vor-digitale) Geschichte
● Sicherheit / Security
● Stabilität – keine Abstürze, Code verhält sich vorhersehbar
● Verwandt mit Schutz & Sicherung (security safety) ↔
● Software/Code soll
– sich „wohl verhalten“ und
– sich selbst schützen ‼
Daten?
● Code ≠ Daten, Daten ≠ Code – selten 😉
● Von-Neumann-Architektur der Computer
● Daten werden oft interpretiert
● Annahmen
● Software steckt voller Vermutungen
● Code benötigt klare interne Zustände
● Buzzwords und Trends 🦄
● Cloud, Virtual, Hyper, Blockchain, holistisch, …
● CI, [Dev|Sec|Ops|Ups|Aha|Tst|Out], Agile, …
Secure Coding
Secure Coding
Secure Coding
● Secure Coding
● soll Sicherheit adressieren und Bugs vermeiden
● >90% basierend auf Geisteshaltung, nicht Tools!
● Secure Coding = zusätzlicher Code → „weakest link“
● Verfügbar für Betriebssysteme und Applikationen
● Legacy Code und ausgewählte Plattformen fallen raus
● überlieferte Bibliotheken
● Firmware (proprietäre Blobs)
● diverse Spezialfälle
!Secure Coding
● Trugschlüsse
● Address Space Layout Randomisation (ASLR)
● Buffer/Stack Overflow Protection
● No-eXecute (NX) Technologien
● → Air Bags für Software/Code
● Technologien wirken nach dem Versagen
● Beheben keine kritischen Bugs
● Dämmen Schaden bestenfalls ein
● Applikation versagt trotzdem
Secure Coding Umsetzung
● Code Base mit Secure Coding Checklisten vergleichen
● Volltextsuche nach gefährlichen Schlüsselworten
● Suchen und Ersetzen nach Checklisten
● Kryptographie hinzufügen ( ) ⁉
● Authentisierung/Autorisierung hinzufügen ( ) ‼
● Neu übersetzen / Analyzer bemühen, neues Deployment
● Im Zweifel auf „nur für internen Gebrauch“ hinweisen
● #win #marketing #release #upgrade
Secure Coding - Eigenheiten
● Anleitungen / Checklisten sind hilfreich
● Air Bags und Brandschutztüren sind nützlich
● Zusätzlich notwendig:
● Eigenheiten der Plattform(en) kennen
● Komponenten gründlich prüfen
● Code möglichst hinterhältig testen
Horrow Show - Typkonversion
<?php
$foo = "0"; // ist ein String (ASCII 48)
$foo += 2; // ist nun ein Integer (2)
$foo = $foo + 1.3; // ist nun Fließkomma (3.3)
$foo = 5 + "10 Little Piggies"; // ist wieder Integer (15)
$foo = 5 + "10 Small Pigs"; // bleibt Integer (15)
?>
Feature ist nicht auf PHP beschränkt. “Hilfreiche” Typkonversionen findet man oft in
Skriptsprachen. Jeder Code mit n>10 Zeilen muss starke Datentypen verwenden oder
ganz genau prüfen.
Horrow Show – Out of Bounds
#include <iostream>
#include <vector>
using namespace std;
int main() {
int mark[5] = { 19, 10, 8, 17, 9 }; // wie in C
vector <int> vect { 1, 2, 3, 4, 5 }; // „neues“ C++ Feature 😼 int n = vect.size();
cout << "Size of the vector is :" << n << endl;
cout << "mark[4] = " << mark[4] << endl;
cout << "mark[5] = " << mark[5] << endl;
cout << "vect[4] = " << vect[4] << endl;
cout << "vect[5] = " << vect[5] << endl;
cout << "vect[4] = " << vect.at(4) << endl;
cout << "vect[5] = " << vect.operator[](5) << endl;
cout << "vect[5] = " << vect.at(5) << endl;
}
Exkurs: Undefined Behaviour
● Konstrukte können kompletten Code „ungültig“ machen
● In C beispielsweise:
Gilt auch teilweise für andere Sprachen oder Szenarien, in denen man programmiert.
Exkurs: Undefined Behaviour
● Analogie aus der Mathematik:
Quelle: https://de.wikipedia.org/wiki/Trugschluss_(Mathematik)
Horrow Show – Integer Overflow
● Mathematisch immer korrekt:
● x+1 > x
● In Code immer ein potentieller Überlauf
● Datentypen sind beschränkt
● Analog x > x-1
● y[i+1]
● n++
● m--
Horror Show - Serialisierung
● Annahme Server hat folgenden Java™ Code
@Bean(name = "/service/toupper")
RemoteExporter exporterServiceRemote() { var exp = new HttpInvokerServiceExporter();
exp.setServiceInterface(UpperCaseService.class);
exp.setService((UpperCaseService)String::toUpperCase);
exp.setAcceptProxyClasses(false);
return exp;
}
Quelle: https://ttulka.medium.com/insecure-deserialization-explained-with-examples-in-java-b599b662599f
Horror Show - Serialisierung
● Client schickt folgenden Java™ Code an Server:
static { try {
Runtime.getRuntime()
.exec("touch /HACKED");
} catch (IOException e) { } }
curl -XPOST -H "Content-Type: application/x-java-serialized-object" \ http://127.0.0.1:8080/service/toupper --data-binary @exploit.ser
→ serialisiert in exploit.ser Datei
Horrow Show – unbedarfte Parser
XML Billion Laughs Attack
Quelle: https://en.wikipedia.org/wiki/Billion_laughs_attack
Cargo Cult Tooling
● “Ja, aber meine Programmiersprache ist von Haus aus sicher!”
● Nein,weil Code
● mit Komponenten interagiert,
● Netzwerke verwendet und
● Daten speichern/lesen muss.
Übersicht typische Fehler
● 2020 CWE Top 25 Most Dangerous Software Weaknesses
● OWASP Top 10 Web Application Security Risks
● Google Project OSS Fuzz:
Komponenten
Quelle: https://signal.org/blog/cellebrite-vulnerabilities/
Secure Design
Secure Design
Secure Design Vorbereitungen
● Klassifizierung ✍
● Welche Daten werden verarbeitet? Wie schauen sie genau aus?
● Wer produziert/konsumiert Daten?
● Übergänge identifizieren 🛂
● Welche Grenzen überschreiten die Daten?
● Welche Teile kommunizieren womit? Wie? Warum?
● Wiederholung für interne Übergänge
● Interne Zustände verfolgen 🛃
● Kryptographische Algorithmen müssen Zustände beschreiben
Kenne die Plattform!
● Hardware 🔌
● Alle Prozessoren enthalten Fehler
● x86/x86_64 CPUs untereinander inkompatibel (-march=native)
● Features ändern Verhalten von Code
● Compiler / Interpreter / JIT Konstrukte
● Betriebssysteme 💻
● Was passiert wirklich mit Daten im Speicher?
● Bibliotheken 📜
Bedrohungsanalyse
● Gehört zur Vorbereitung, aber bedeutet…
● Top n Checklisten suchen,
● Zahlen für Schadensermittlung erfinden,
● Folgen und Wahrscheinlichkeit schätzen und
● die Zukunft (für die Applikation) modellieren.
● Idealer Job für Controller 💹
● hält Budget im Zaum
● hilft Produktentwicklung zu steuern
● befreit gebundene Ressourcen
Secure Design Prinzipien (§)
● Angriffsoberfläche minimieren
● Sichere Defaults einführen, behalten und benutzen
● Principle of least Privilege
● Principle of Defence in Depth
● Sicher versagen – mehr als nur Exceptions verwenden
● Diensten / Dritten nicht vertrauen
● Funktionstrennung (separation of duties)
● Keine Security durch Obscurity
● Keep it simple 😸
Secure Design Konzepte
● Secure Design ist Teil des Konzepts, nicht des Codes!
● Beginn (weit) vor der ersten Zeile Code
● Secure Design impliziert Secure Coding
● Prinzipien erfordern sichere Implementierung
● unsichere Komponenten dürfen nicht teilnehmen
● ausgedehnt auf Protokolle und Datenformate
● Secure Design ist Bestandteil aller Schritte
● Konzept, Design (auch UI!), Code, Testen, Deployment, …
● Daten! - Datenverarbeitung und -haltung
Secure Design – Bad News!
● Defekte Architekturen sind nicht reparierbar ☢ ☣ ⚠
● Hardwarefehler, Protokolle, Plattformen, Toolchains, …
● Workarounds beginnen 10 Minuten nach dem Design 🛠
● Komplexe Datenformate (PDF, Office Dokumente, Multimedia, …)
● Anforderungen (PKI, Crypto, Schlüssel, Speicherplatz, CPU, …)
● Komponenten (Container all teh things! ) 😹
● Abhilfe: Gleich mit Fehlern beginnen! 😼
Failure Development
● Instabilität kann in Code durch
● manipulierte Daten oder
● logische Konstrukte eingeführt werden.
● Code muss elegant versagen ☠
● Kein undefiniertes Verhalten
● Arbeiten unter Last
● Arbeiten mit fehlenden Ressourcen
Linux® Kernel Fault Injection
● Linux® Kern erlaubt Injektion von Fehlern
● Funktionen (system calls) Fehlercodes liefern
● Intervall und Wahrscheinlichkeit konfigurierbar
● Verfügbar für Storage, Dateisysteme, bestimmte Subsysteme
● Nützlich für Debugging
● Leicht zu verwenden
● Teil des Standardkerns, frei verfügbar
● Kann via debugfs oder procfs gesteuert werden
Beispiel: Fault Injection
● mount debugfs /debug -t debugfs
● cd /debug/fail_make_request
● echo 10 > interval # Intervall
● echo 100 > probability # 100% Wahrscheinlichkeit
● echo -1 > times # Wie oft: -1 bedeutet kein Limit
● mount -t logfs /dev/sdb1 /mnt/2
● echo 1 > /sys/block/sdb/sdb1/make-it-fail
Beispiel: Fault Injection
FAULT_INJECTION: forcing a failure
…[<c01672f6>] do_sync_write+0xc4/0x101 [<c0167af5>] vfs_write+0xaf/0x138
[<c0167fe2>] sys_write+0x3d/0x61
[<c0103da2>] sysenter_past_esp+0x5f/0x99
=======================
Buffer I/O error on device sdb1, logical block 35497 kernel BUG at fs/logfs/gc.c:88!
invalid opcode: 0000 [#1]
PREEMPT
Modules linked in: iptable_nat nf_nat ipt_ULOG ipt_recent nf_conntrack_ipv4 xt_state nf_conntrack
nfnetlink ipt_REJECT xt_tcpudp iptable_filter ip_tables x_tables capability usblp commoncap loop dm_mod video thermal sbs fan container dock battery ac floppy …
CPU: 0
EIP: 0060:[<c01bd9fc>] Tainted: P VLI…
🎲 Fuzzing 🎰
● Fuzzing benutzt Zufallsdaten als Eingabe für Code
● bekannt seit den 1950ern (Verwendung defekter Lochkarten)
● Forschungsgebiet der Informatik seit 1981 🔬
● Strategien
● komplett zufällige Daten
● strukturbewusste zufällige Daten
● struktur- und codebewusste zufällige Daten
● Black / White Box Modell
● Standardwerkzeug der Softwareentwicklung (eigentlich…)
Fuzzing?
Füttern des Codes mit Zufallsdaten:
Oder alternativ:
Implementationen
● Fuzzing mit reinen Daten
● Fuzzer erzeugt Daten
● Applikation versucht zu verarbeiten
● Fuzzing mit Hooks im Code
● gezieltes Einschleusen von Daten
● besseres Testen von “tiefen” Komponenten
● Erreichen von mehr Code Pfaden
Zusammenfassung
Secure Coding ≠ Secure Design.
Secure Design ≠ Design.
– Zusätzliche Anforderungen notwendig.
– Muss mit Softwareentwicklung integriert werden.
Manche Applikationen werden Secure Design/Coding nie verwenden.
Lieblingshardware, -software, -bibliothek ist wahrscheinlich defekt.
Softwareentwicklung muss mit Versagen geschehen. 🙀 😻
Eigene Applikation einfach mal ein Paar Monate ins Internet stellen. 😈
Fragen?
virtual
logical
electronics I/O CPU memory
HI char devices
HI subsystems
protocol families sockets access
protocols
network interface
networking
Virtual File System
block devices
storage
virtual memory memory access
logical memory
Page Allocator
memory
threads processes
Scheduler
interrupts core
CPU specific
processing
generic HW access system run
system functionalities
layers
interfaces core
Linux kernel map
logical file systems
abstract devices and HID class drivers
HI peripherals device drivers
2.6.36
network device drivers
device control
disk controller drivers physical memory
operations device access
and bus drivers
user space interfaces
hardware interfaces
files & directories access
user peripherals disk controllers network controllers
human interface
synchronization Device Model
swap
networking storage memory
mapping security
bridges
debugging page cache socket
splice
sys_init_module
timer_interrupt jiffies_64 do_timer tick_periodic
context_switch
alloc_file
registers RAM MMU
I/O ports I/O mem keyboard
mouse graphics card audio APIC DMA SCSI SATA Ethernet WiFi
physically mapped memory system files
copy_from_user
sys_write sys_open sys_execve
linux_binfmt
vfs_read
task_struct
usb_driver
sys_socketcall
socket
interrupt sys_fork
schedule
do_IRQ rq
kmalloc
kmem_cache vmalloc vmlist
page
do_page_fault outw
cdev /sysfs /dev
readw /proc cdev_add
oss
mousedev kbd
i8042_driver psmouse
atkbd_drv tty
console snd_fops video_fops console_fops
vga_con
pt_regs
__get_free_pages vm_struct
sys_mmap
/proc/self/maps
timer_list
do_softirq tasklet_struct
request_queue setup_irq
init_scsi
ext4_file_operations
gendisk block_device_operations
sys_sync sys_nanosleep
schedule_timeout sysfs_ops
mm_struct module
cdev_map
request_region
proto_ops
socket_file_ops
/proc/net/protocols proto
tcp_prot inet_stream_ops inet_dgram_ops
udp_prot inet_family_ops
__sock_create
ip_rcv
net_device alloc_netdev_mq ieee80211_alloc_hw file_operations
sys_syslog
aic94xx_init usb_hcd
ehci_irq
usb_hcd_irq usb_submit_urb
ehci_urb_enqueue usb_hcd_giveback_urb
pci_driver start_kernel
init/main.c
run_init_process do_initcalls
sys_reboot
do_mmap_pgoff sys_brk
arch/x86/
irq_desc setup_timer process_timeout
activate_task
sys_clone sys_vfork
file
vm_area_struct
inode fs/exec.c
address_space
ip_queue_xmit
dev_queue_xmit netif_rx
ether_setup
ieee80211_xmit ieee80211_rx sd_fops
scsi_device scsi_driver
sys_socket linux/syscalls.h
linux/uaccess.h
pci_read pci_write ioremap
request_mem_region
kernel_power_offkernel_restart
writew
inw
inet_create vfs_write
ipw2100_pci_init_one zd1201_probe unix_family_ops sys_mount
load_module
ext4_get_sb file_system_type
get_sb super_block
__alloc_pages
die /proc/interrupts
cli sti switch_to system_call
trap_init
sys_read do_path_lookup
vfs_create
kernel/sched.c
drivers/net/
show_regs
block/
drivers/
drivers/input/ drivers/media/ sound/
init/
kernel/
include/asm/
mm/slob.c /proc/slabinfo
ac97_driver
usb_storage_driver bus_type
device
device_driver probe class
device_create
driver_register drivers/base/
kobject security/
linux/security.h
selinux_ops security_ops security_socket_create security_inode_create
pci_register_driver
ahci_pci_driver libata Scsi_Host may_open
create_workqueue
alloc_skb alsa
inode_operations
ramfs_fs_type
iscsi_tcp_transport smb_fs_type cifs_file_ops nfs_file_operations
sk_buff mm/mmap.c
vma_link
start_thread
find_vma_prepare
virt_to_page
fb_ops
pci_request_regions fb_fops
cdev_add register_chrdev
kset
msleep
do_fork kernel_thread current thread_info
semaphore workqueue_struct work_struct
kthread_create
wake_up
atomic_t mutex add_timer
down_interruptible
kswapd do_swap_page mm/ fs/
kernel/
net/
kmem_cache_alloc kernel/
mousedev_handler input_fops
get_page_from_freelist
wakeup_kswapd
try_to_free_pages
zone
drivers/media/video/
video_device NF_HOOK
nf_hooks
tcp_transmit_skb
drivers, registers and interrupts
tcp_sendmsg tcp_recvmsg udp_sendmsg udp_recvmsg
netif_receive_skb linux/netdevice.h
ip_output System Call Interface
/dev/mem mem_fops mmap_mem
sock_ioctl
dev_ioctl linux/device.h
linux/kobject.h
device_type driver_init
arch/x86/mm/
sys_signal
++
request_irq sys_times sys_time
sys_gettimeofday sys_futex system calls
and system files
cross-functional modules
sys_mprotect sys_pivot_root
mount_root
kernel/signal.c sys_kill
shm_vm_ops sys_shmctl sys_shmat
sys_newfstat sys_select sys_chroot
kvm_dev_ioctl
kvm
camera interrupt
controller USB
controller PCI controller uvc_driver
sys_ioctl
register_netdev lock_kernel
kernel_flag do_sigaction
sys_pipe
sys_fsync
vfs_fsync
bdi_writeback_thread do_writepages fget
fd
sys_sysfs
file_systems sys_flock sys_mkdir
sys_inotify_init sys_chdir
vfs_getattr vfs_fstat sys_epoll_create
kmem_cache_alloc inode_permission
notify_change inode_setattr sys_chmod sys_readv
iovec sys_poll sys_tee sys_sysinfo
sys_swapon
swap_info sys_msync
do_mmap
up mutex_unlock mutex_lock_interruptible
pgd_t pmd_t pte_t
setup_arch
mm_init
kmem_cache_init
vm_stat sys_capset
x86_init
zonelist kfree
__free_pages __free_one_page security_capset
handle_sysrq printk
log_buf
kgdb_breakpoint sys_ptrace
oprofile_init oprofile_start register_kprobe
kernel_param
native_init_IRQ set_intr_gate schedule_work
tasklet_action
softirq_init module_param
bus_register
mem_init vmalloc_init /sys/class/
kobject_uevent_init kobject_uevent
fsnotify sys_fanotify_init
drm_driver
out_of_memory vfree
. .
sys_chown fsnotify_change
fanotify_handle_event /proc/meminfo
totalram_pages
num_physpages
INIT_WORK queue_work
usb_stor_host_template
scsi_host_alloc sys_getdents
ext4_readdir
generic_file_aio_read
free_list free_area
N R_FREE_PAGES
/proc/net/
tcp4_seq_show sg_proc_seq_show_dev rt_cache_seq_show sys_connect
sys_accept sys_bind sys_listen sys_sendmsg sys_recvmsg sys_setsockopt
sock_sendpage
sock_splice_read sys_sendfile
do_splice_direct sys_splice
e1000_xmit_frame e1000_intr
usbnet_probe netif_carrier_on ip_route_input udp_rcv tcp_v4_rcv
ip_local_deliver ip_push_pending_frames functions
implementations
boot, shutdown power management
hibernate machine_ops
early_trap_init
inet_init
udp_sendpage tcp_sendpage
tcp_splice_read spin_unlock_irqrestorespin_lock_irqsave
wait_event wait_for_completion
complete owner run_timer_softirq
si_meminfo
si_swapinfo sys_mincore
ACPI
mm/slub.c mm/slab.c