Detailed Course Outline
DAY 1
Cyber security basics
- What is security?
 - Threat and risk
 - Cyber security threat types
 - Consequences of insecure software
- Constraints and the market
 - The dark side
 
 - Categorization of bugs
- The Seven Pernicious Kingdoms
 - SEI CERT Secure Coding Guidelines
 
 - Coding standards in automotive
- ISO 26262
 - MISRA C 2012
 - MISRA C++ 2008
 - AUTOSAR C++14 and the future
 - CERT C Coding Standard
 - CERT C++ Coding Standard
 
 - Cyber security in the automotive sector
- Software security in the automotive world
 - Threats and trends in automotive
 - Self-driving car threats
 - The CAN bus and security
 - Case study – controlling the CAN bus through the infotainment system
 
 
Buffer overflow
- Assembly basics and calling conventions
- ARM assembly essentials
 - Registers and addressing
 - Basic ARM64 instructions
 - ARM calling conventions
- The calling convention
 - The stack frame
 - Calling convention implementation on ARM64
 - Stacked function calls
 
 
 - Memory management vulnerabilities
- Memory management and security
 - Vulnerabilities in the real world
 - Mapping to MISRA
 - Buffer security issues
 - Buffer overflow on the stack
- Buffer overflow on the stack – stack smashing
 - Exploitation – Hijacking the control flow
 - Lab – Buffer overflow 101, code reuse
 - Exploitation – Arbitrary code execution
 - Injecting shellcode
 - Lab – Code injection, exploitation with shellcode
 
 - Buffer overflow on the heap
- Unsafe unlinking
 - Case study – Heartbleed
 
 - Pointer manipulation
- Modification of jump tables
 - Overwriting function pointers
 
 
 - Best practices and some typical mistakes
- Unsafe functions
 - Dealing with unsafe functions
 - Lab – Fixing buffer overflow
 - What’s the problem with asctime()?
 - Lab – The problem with asctime()
 - Using std::string in C++
 
 
DAY 2
Buffer overflow
- Some typical mistakes leading to BOF
- Unterminated strings
 - readlink() and string termination
 - Manipulating C-style strings in C++
 - Malicious string termination
 - Lab – String termination confusion
 - String length calculation mistakes
 - Off-by-one errors
 - Allocating nothing
 
 
Memory management hardening
- Mapping to MISRA
 - Securing the toolchain
- Securing the toolchain in C and C++
 - Compiler warnings and security
 - Using FORTIFY_SOURCE
 - Lab – Effects of FORTIFY
 - AddressSanitizer (ASan)
- Using AddressSanitizer (ASan)
 - ASan changes to the prologue
 - ASan changes to memory read/write operations
 - ASan changes to epilogue
 
 - Stack smashing protection
- Detecting BoF with a stack canary
 - Argument cloning
 - Stack smashing protection on various platforms
 - SSP changes to the prologue and epilogue
 - Lab – Effects of stack smashing protection
 
 
 - Runtime protections
- Runtime instrumentation
 - Address Space Layout Randomization (ASLR)
- ASLR on various platforms
 - Lab – Effects of ASLR
 - Circumventing ASLR – NOP sleds
 - Heap spraying
 
 - Non-executable memory areas
- The NX bit
 - Write XOR Execute (W^X)
 - NX on various platforms
 - Lab – Effects of NX
 - NX circumvention – Code reuse attacks
- Return-to-libc / arc injection
 
 - Return Oriented Programming (ROP)
- Lab – ROP demonstration
 - Protection against ROP
 
 
 
 
Common software security weaknesses
- Security features
- Authentication
- Authentication basics
 - Multi-factor authentication
 - Authentication weaknesses – spoofing
 - Case study – Hacking the Mitsubishi Outlander PHEV hybrid
 
 - Password management
- Inbound password management
- Storing account passwords
 - Password in transit
 - Lab – Is just hashing passwords enough?
 - Dictionary attacks and brute forcing
 - Salting
 - Adaptive hash functions for password storage
 - Password policy
- NIST authenticator requirements for memorized secrets
 
 - Case study – The Ashley Madison data breach
- The dictionary attack
 - The ultimate crack
 - Exploitation and the lessons learned
 
 - Password database migration
 
 - Outbound password management
- Hard coded passwords
 - Best practices
 - Lab – Hardcoded password
 - Protecting sensitive information in memory
- Challenges in protecting memory
 - Heap inspection
 - Compiler optimization challenges
 - Lab – Zeroization challenges
 - Sensitive info in non-locked memory
 
 
 
 - Inbound password management
 - Authorization
- Access control basics
 - File system access control
- Improper file system access control
 - Ownership
 - chroot jail
 - Using umask()
 - Linux filesystem
 - LDAP
 
 
 
 - Authentication
 
DAY 3
Common software security weaknesses
- Input validation
- Input validation principles
- Blacklists and whitelists
 - Data validation techniques
 - What to validate – the attack surface
 - Attack surface in automotive
 - Where to validate – defense in depth
 - How to validate – validation vs transformations
 - Output sanitization
 - Encoding challenges
 - Validation with regex
 - Mapping to MISRA
 
 - Injection
- Injection principles
 - Injection attacks
 - Code injection
- OS command injection
- Lab – Command injection
 - OS command injection best practices
 - Avoiding command injection with the right APIs
 - Lab – Command injection best practices
 - Case study – Shellshock
 - Lab – Shellshock
 - Case study – Command injection in Jeep Cherokee
 
 - Process control – library injection
- DLL hijacking
 - Lab – DLL hijacking
 
 
 - OS command injection
 
 - Integer handling problems
- Representing signed numbers
 - Integer visualization
 - The MISRA essential type model
 - Integer promotion
 - Composite expressions and type conversion
 - Integer overflow
 - Lab – Integer overflow
 - Signed / unsigned confusion
 - Lab – Signed / unsigned confusion
 - Integer truncation
 - Lab – Integer truncation
 - Case study – WannaCry
 - Best practices
- Upcasting
 - Precondition testing
 - Postcondition testing
 - Using big integer libraries
 - Best practices in C
 - Lab – Handling integer overflow on the toolchain level in C/C++
 - Best practices in C++
 - Lab – Integer handling best practices in C++
 
 
 - Other numeric problems
- Security issues with bitfields
 - Division by zero
 - Working with floating-point numbers
 
 - Files and streams
- Path traversal
 - Path traversal-related examples
 - Lab – Path traversal
 - Link and shortcut following
 - Virtual resources
 - Path traversal best practices
 - Lab – Path canonicalization
- Format string issues
 - The problem with printf()
 - Lab – Exploiting format string
 
 
 
 - Input validation principles
 
DAY 4
Common software security weaknesses
- Time and state
- Mapping to MISRA
 - Race conditions
- Race condition in object data members
 - File race condition
- Time of check to time of usage – TOCTTOU
 - Lab – TOCTTOU
 - Insecure temporary file
 
 - Potential race conditions in C/C++
- Race condition in signal handling
 - Forking
 - Bit-field access
 
 
 
 - Errors
- Error and exception handling principles
 - Mapping to MISRA
 - Error handling
- Returning a misleading status code
 - Error handling in C
 - Error handling in C++
 - Using std::optional safely
 - Information exposure through error reporting
 
 - Exception handling
- In the catch block. And now what?
 - Empty catch block
 - Exception handling in C++
 - Lab – Exception handling mess
 
 
 - Code quality
- Data handling
- Type mismatch
 - Lab – Type mismatch
 - Initialization and cleanup
- Constructors and destructors
 - Initialization of static objects
 - Lab – Initialization cycles
 
 - Unreleased resource
- Array disposal in C++
 - Lab – Mixing delete and delete[]
 
 
 - Control flow
- Incorrect block delimitation
 - Dead code
 - Leftover debug code
 - Backdoors, dev functions and other undocumented functions
 - Using if-then-else and switch defensively
 
 - Signal handling
- Signal handlers
 - Best practices
 
 - Object oriented programming pitfalls
- Inheritance and object slicing
 - Implementing the copy operator
 - The copy operator and mutability
 - Mutability
- Mutable predicate function objects
 - Lab – Mutable predicate function object
 
 
 - Memory and pointers
- Memory and pointer issues
 - Pointer handling pitfalls
 - Alignment
 - Null pointers
- NULL dereference
 - NULL dereference in pointer-to-member operators
 
 - Pointer usage in C and C++
- Use after free
 - Lab – Use after free
 - Lab – Runtime instrumentation
 - Double free
 - Memory leak
 - Smart pointers and RAII
 - Smart pointer challenges
 - Incorrect pointer arithmetics
 
 
 - File I/O
- Working with file descriptors, structures and objects
 - File reading and writing
 - File access functions and methods
 
 
 - Data handling
 
Using vulnerable components
- Assessing the environment
 - Hardening
 - Vulnerability management
- Patch management
 - Bug bounty programs
 - Vulnerability databases
 - Vulnerability rating – CVSS
 - Lab – Finding vulnerabilities in third-party components
 - DevOps, the build process and CI / CD
 - Insecure compiler optimization
 
 
Security testing
- Security testing vs functional testing
 - Manual and automated methods
 - Security testing techniques and tools
- Code analysis
- Security aspects of code review
 - Static Application Security Testing (SAST)
 - Lab – Using static analysis tools
 
 - Dynamic analysis
- Security testing at runtime
 - Penetration testing
 - Stress testing
 - Dynamic analysis tools
- Dynamic Application Security Testing (DAST)
 
 - Fuzzing
- Fuzzing techniques
 - Fuzzing – Observing the process
 
 
 
 - Code analysis
 
Wrap up
- Secure coding principles
- Principles of robust programming by Matt Bishop
 - Secure design principles of Saltzer and Schröder
 
 - And now what?
- Software security sources and further reading
 - C and C++ resources
 - Links to automotive coding standards