Security: Lessons from the Past Decade

Download Report

Transcript Security: Lessons from the Past Decade

Software Security:
Lessons from the Past Decade
Vitaly Shmatikov
The University of Texas at Austin
“Vulnerability of the decade”
• 87 of 126 CERT security advisories in 20002004 are memory-corruption vulnerabilities
– 73 are in applications providing remote services
(HTTP servers, database services, remote login
services, mail and FTP)
• Most involve illegitimate control transfers
– Jumps to injected attack code, return-to-libc, etc.
• Can also target configurations, user data and
decision-making values
slide 2
Stack corruption
int bar (int val1) {
int val2;
foo (a_function_pointer);
}
Contaminated
memory
int foo (void (*funcp)()) {
char* ptr = point_to_an_array;
char buf[128];
gets (buf);
strncpy(ptr, buf, 8);
Most popular
(*funcp)();
target
}
String
grows
val1
val2
arguments
(funcp)
return address
Previous Frame Pointer
pointer var
(ptr)
buffer
(buf)
Stack
grows
slide 3
Target #1: return address
② set stack pointers to
return to a dangerous
library function
“/bin/sh”
Attack code
①
① Change the saved return address to
point to the attack code. After the
function returns, control is
transferred to the attack code.
② … or return-to-libc: use existing
instructions in the code segment such
as system(), exec(), etc. as the attack
code.
args
(funcp)
system()
return address
PFP
pointer var
(ptr)
buffer
(buf)
slide 4
Target #2: frame pointer
Fake return addr
Fake PFP
Attack code
args
(funcp)
return address
PFP
① Change the caller’s saved frame pointer
to point to attacker-controlled memory.
Caller’s return address will be read
from this memory.
pointer var
(ptr)
buffer
(buf)
slide 5
Target #3: pointer variables
Attack code
Global Offset Table
Function pointer
① Change a function pointer to point to
the attack code.
② Any memory, even outside the stack, can
be modified by the statement that stores
a value into the compromised pointer.
strncpy(ptr, buf, 8);
*ptr = 0;
①
args
(funcp)
return address
②
PFP
pointer var
(ptr)
buffer
(buf)
slide 6
Preventing memory attacks
Use safe programming languages, e.g., Java
Black-box testing with long strings
Mark stack as non-executable
Randomize memory layout or encrypt return
address on stack by XORing with random string
• Run-time checking of array and buffer bounds
•
•
•
•
– StackGuard, libsafe, many other tools
• Static analysis of source code to find overflows
slide 7
WX / DEP
• Mark all writeable memory locations as nonexecutable
– Microsoft’s DEP (Data Execution Prevention)
– This blocks all code injection exploits
• Hardware support
– AMD “NX” bit, Intel “XD” bit (in post-2004 CPUs)
• Widely deployed
– Windows (since XP SP2), Linux (via PaX patches),
OpenBSD, OS X (since 10.5)
slide 8
What does WX not prevent?
• Can still corrupt stack
• If fake “return address” points into existing
code, WX will not block control transfer
• This is the basis of return-to-libc exploits
– Overwrite saved EIP with address of any library
routine, arrange memory to look like arguments
• Return-oriented programming allows arbitrary
computation (without code injection!)
slide 9
StackGuard
• Embed “canaries” in stack frames and verify
their integrity prior to function return
– Any overflow of local variables will damage canary
buf
Local variables
canary
sfp
ret
addr
Frame of the
calling function
Top of
stack
Return
Pointer to
previous execution to
this address
frame
• Choose random canary string on program start
• Terminator canary: “\0”, newline, linefeed, EOF
– String functions like strcpy won’t copy beyond “\0”
slide 10
Breaking StackGuard
• Microsoft Windows 2003: if canary is
damaged, exception is generated and
exception handler is called
buf
canary
sfp
ret
addr
exception
handler
Top of
stack
• Litchfield’s attack smashes the canary and
overwrites the pointer to the exception
handler with the address of the attack code
– Similar exploit used by CodeRed worm
slide 11
Safe exception handling
• Exception handler record must
1. Be on the stack of the current thread
2. Point outside the stack
3. Point to a valid handler
• Microsoft’s /SafeSEH linker option: header of the binary
lists all valid handlers
• Exception handler records must form a linked
list, terminating in FinalExceptionHandler
– Address of FinalExceptionHandler is randomized
slide 12
When SafeSEH is incomplete
Sotirov and Dowd
• If DEP is disabled, handler is allowed to be on
any non-image page except stack
– Put attack code on the heap, overwrite exception
handler record on the stack to point to it
• If any module is linked without /SafeSEH,
handler can be anywhere in this module
– Overwrite exception handler record on the stack
to point to a suitable place in the module
– Used to exploit Microsoft DNS RPC vulnerability
in Windows Server 2003
slide 13
Many other memory attacks
• Bypass address-space randomization
– Heap spraying and other techniques
• Bypass non-executable memory
– Exploit “found” code sequences
– Return-oriented and jump-oriented programming
• Bypass safe exception handling
• But also many good defenses!
slide 14
Future attacks
• Use safe programming languages, e.g., Java
• Still vulnerable to memory-corruption attacks
on native methods, but much safer in general
• What will be the “vulnerability of the decade” in
2010-2020?
• My answer: semantic vulnerabilities
slide 15
Semantic vulnerabilities
• Omitted security checks
• Misconfigured security policies
• Execution of untrusted code in wrong
contexts
• Denial of service due to resource exhaustion
– Non-terminating loops, deep recursion, worstcase behavior of data structures…
slide 16
Acknowledgements
• M. Bond, R. Chang, K. McKinley, S. Son,
V. Srivastava
slide 17
Java access-rights model
• Before doing anything security-sensitive, Java
library code must check that the calling
application has the required permissions
– Example: before establishing a network
connection, verify that calling code has the right to
access the network
• Checks are performed via calls to methods in
the SecurityManager class
slide 18
classLoader.loadClass(“java.util.HashSet”);
How an applet loads a class
slide 19
classLoader.loadClass(“java.util.HashSet”);
loadClass(name) {
...
if (name.lastIndexOf(‘.’) != -1)
securityManager.checkPackageAccess(name);
...
super.loadClass();
}
slide 20
classLoader.loadClass(“java.util.HashSet”);
loadClass(name) {
...
if (name.lastIndexOf(‘.’) != -1)
securityManager.checkPackageAccess(name);
...
super.loadClass();
SecurityManager.checkPackageAccess()
}
Access-control check
slide 21
classLoader.loadClass(“java.util.HashSet”);
loadClass(name) {
...
if (name.lastIndexOf(‘.’) != -1)
securityManager.checkPackageAccess(name);
...
super.loadClass();
SecurityManager.checkPackageAccess()
}
ClassLoader.loadClass():341
FileURLLoader.getResource():73
walkPathComponents() {
...
121: { ... if (file.exists()) ... }
...
139: { ... if (file.exists()) ... }
...
}
slide 22
classLoader.loadClass(“java.util.HashSet”);
loadClass(name) {
...
if (name.lastIndexOf(‘.’) != -1)
securityManager.checkPackageAccess(name);
...
super.loadClass();
SecurityManager.checkPackageAccess()
}
ClassLoader.loadClass():341
FileURLLoader.getResource():73
walkPathComponents() {
...
121: { ... if (file.exists()) ... }
...
139: { ... if (file.exists()) ... }
...
}
File.exists():268
File.checkRead():1485
SecurityManager.checkRead()
slide 23
classLoader.loadClass(“sun/applet/AppletClassLoader”);
Sun Java Virtual Machine 1.3
slide 24
classLoader.loadClass(“sun/applet/AppletClassLoader”);
loadClass(name) {
...
if (name.lastIndexOf(‘.’) != -1)
securityManager.checkPackageAccess(name);
...
super.loadClass();
}
slide 25
classLoader.loadClass(“sun/applet/AppletClassLoader”);
loadClass(name) {
...
if (name.lastIndexOf(‘.’) != -1)
securityManager.checkPackageAccess(name);
...
super.loadClass();
SecurityManager.checkPackageAccess()
}
slide 26
classLoader.loadClass(“sun/applet/AppletClassLoader”);
loadClass(name) {
...
if (name.lastIndexOf(‘.’) != -1)
securityManager.checkPackageAccess(name);
...
super.loadClass();
SecurityManager.checkPackageAccess()
}
ClassLoader.loadClass():341
FileURLLoader.getResource():73
walkPathComponents() {
...
121: { ... if (file.exists()) ... }
...
139: { ... if (file.exists()) ... }
...
}
File.exists():268
File.checkRead():1485
SecurityManager.checkRead()
slide 27
Detecting this vulnerability
• Unlike memory-corruption exploits, this
attack does not violate language semantics
– No injected code
– No violations of memory- or type-safety
– Execution path is present in the original code, thus
no violations of control-flow integrity!
slide 28
No specification available
• Execution path associated with the attack is
“unusual” (i.e., not part of specification)
• What is the specification for access-control
policy in Java libraries?
– Not part of the library
slide 29
Inferring policies
• Dynamically
– Training: observe many executions of the code,
create patterns
– Deployment: flag deviations from pattern library
• Statically
– Manually specify policy
– Mine source code for common check-beforeevent patterns
– Complete static analysis (challenging)
slide 30
classLoader.loadClass(“sun/applet/AppletClassLoader”);
loadClass(name) {
...
if (name.lastIndexOf(‘.’) != -1)
securityManager.checkPackageAccess(name);
...
super.loadClass();
SecurityManager.checkPackageAccess()
}
ClassLoader.loadClass():341
Infer policy from dynamic behavior?
FileURLLoader.getResource():73
walkPathComponents() {
...
121: { ... if (file.exists()) ... }
...
139: { ... if (file.exists()) ... }
...
}
File.exists():268
File.checkRead():1485
SecurityManager.checkRead()
slide 31
loadClass(“java.util.HashMap”);
…  SecurityManager.checkPackageAccess()
…
…  FileURLLoader.getResource():73  walkPathComponents() :121  File.exists()
loadClass(“sun/applet/AppletClassLoader”);
…  SecurityManager.checkPackageAccess()
…
…  FileURLLoader.getResource():73  walkPathComponents() :121  File.exists()
loadClass(“MyClass”);
…  SecurityManager.checkPackageAccess()
…
…  FileURLLoader.getResource():73  walkPathComponents() :139  File.exists()
slide 32
loadClass(“java.util.HashMap”);
Train
…  SecurityManager.checkPackageAccess()
…
…  FileURLLoader.getResource():73  walkPathComponents() :121  File.exists()
loadClass(“sun/applet/AppletClassLoader”);
…  SecurityManager.checkPackageAccess()
Deploy
…
…  FileURLLoader.getResource():73  walkPathComponents() :121  File.exists()
loadClass(“MyClass”);
…  SecurityManager.checkPackageAccess()
…
…  FileURLLoader.getResource():73  walkPathComponents() :139  File.exists()
slide 33
classLoader.loadClass(“MyClass”);
slide 34
classLoader.loadClass(“MyClass”);
loadClass(name) {
...
if (name.lastIndexOf(‘.’) != -1)
securityManager.checkPackageAccess(name);
...
super.loadClass();
}
slide 35
classLoader.loadClass(“MyClass”);
loadClass(name) {
...
if (name.lastIndexOf(‘.’) != -1)
securityManager.checkPackageAccess(name);
...
super.loadClass();
SecurityManager.checkPackageAccess()
}
slide 36
classLoader.loadClass(“MyClass”);
loadClass(name) {
...
if (name.lastIndexOf(‘.’) != -1)
securityManager.checkPackageAccess(name);
...
super.loadClass();
SecurityManager.checkPackageAccess()
}
ClassLoader.loadClass():341
FileURLLoader.getResource():73
walkPathComponents() {
...
121: { ... if (file.exists()) ... }
...
139: { ... if (file.exists()) ... }
...
}
File.exists():268
File.checkRead():1485
SecurityManager.checkRead()
slide 37
loadClass(“java.util.HashMap”);
…  SecurityManager.checkPackageAccess()
…
…  FileURLLoader.getResource():73  walkPathComponents() :121  File.exists()
loadClass(“sun/applet/AppletClassLoader”);
…  SecurityManager.checkPackageAccess()
…
…  FileURLLoader.getResource():73  walkPathComponents() :121  File.exists()
loadClass(“MyClass”);
…  SecurityManager.checkPackageAccess()
…
…  FileURLLoader.getResource():73  walkPathComponents() :139  File.exists()
slide 38
loadClass(“java.util.HashMap”);
…  SecurityManager.checkPackageAccess()
…
…  FileURLLoader.getResource():73  walkPathComponents() :121  File.exists()
loadClass(“sun/applet/AppletClassLoader”);
…  SecurityManager.checkPackageAccess()
…
…  FileURLLoader.getResource():73  walkPathComponents() :121  File.exists()
loadClass(“MyClass”);
…  SecurityManager.checkPackageAccess()
…
…  FileURLLoader.getResource():73  walkPathComponents() :139  File.exists()
slide 39
loadClass(“java.util.HashMap”);
…  SecurityManager.checkPackageAccess()
Train
…
…  FileURLLoader.getResource():73  walkPathComponents() :121  File.exists()
loadClass(“sun/applet/AppletClassLoader”);
…  SecurityManager.checkPackageAccess()
Deploy
…
…  FileURLLoader.getResource():73  walkPathComponents() :121  File.exists()
loadClass(“MyClass”);
…  SecurityManager.checkPackageAccess()
Train
…
…  FileURLLoader.getResource():73  walkPathComponents() :139  File.exists()
slide 40
Access-control policies
• Context-sensitive
– Different checks depending on where the code is
called from
• History-sensitive
– Different checks depending on previously
executed code
• Policy analysis must be very precise!
– Tradeoff between false positives and negatives
– Performance overhead
slide 41
FileURLLoader.walkPathComponents():121
Overhead
FileURLLoader.getResource():73
False positives
ClassLoader.loadClass():341
False negatives
More context sensitivity
ClassLoader.loadClass():312
File.exists():268
File.checkRead():1485
SecurityManager.checkRead()
slide 42
classLoader.loadClass(“java.util.HashSet”);
loadClass(name) {
...
if (name.lastIndexOf(‘.’) != -1)
securityManager.checkPackageAccess(name);
...
super.loadClass();
SecurityManager.checkPackageAccess()
}
ClassLoader.loadClass():341
FileURLLoader.getResource():73
walkPathComponents() {
...
121: { ... if (file.exists()) ... }
...
139: { ... if (file.exists()) ... }
...
}
File.exists():268
File.checkRead():1485
SecurityManager.checkRead()
slide 43
classLoader.loadClass(“java.util.HashSet”);
loadClass(name) {
S ← walkStack ()
...
if (name.lastIndexOf(‘.’) != -1)
check ( S )
securityManager.checkPackageAccess(name);
...
super.loadClass();
SecurityManager.checkPackageAccess()
}
ClassLoader.loadClass():341
FileURLLoader.getResource():73
walkPathComponents() {
...
121: { ... if (file.exists()) ... }
...
139: { ... if (file.exists()) ... }
...
}
File.exists():268
File.checkRead():1485
S ← walkStack ()
check ( S )
SecurityManager.checkRead()
Costs of context sensitivity
200%
Overhead
150%
100%
Walk stack (k = inf)
Walk stack (k = 3)
50%
0%
slide 45
Costs of context sensitivity
200%
Overhead
150%
100%
Proportional to
depth & security calls
High overhead at
security calls
Walk stack (k = inf)
Walk stack (k = 3)
50%
0%
slide 46
Techniques
• Depth-limited context sensitivity
• Efficient (probabilistic) computation of calling
contexts
• Alternative: static analysis
• Main challenge: how do we know that the
access-control policy used for verification and
enforcement is complete and correct?
slide 47
More reading
• Bond et al. “Efficient, Context-Sensitive
Detection of Real-World Semantic Attacks”
(PLAS 2010)
slide 48
Static analysis of security policies
• Approach #1: manually specify which check
must dominate which event, model-check the
source code
• Approach #2: infer common patterns by
mining the source code, flag deviations
– “Bugs as inconsistencies”
slide 49
Subtlety of access-control policies
Source: DatagramSocket.connect (Java Class Library)
isMulticastAddress?
SecurityManager.
SecurityManager.
checkConnect()
checkMulticast()
SecurityManager.
Call connect()
checkAccept()
1. Checks do not dominate the security event
2. This is not a common pattern
slide 50
Our study of Java Class Library
• Well-studied, mature code base
– 3 different implementations (JDK, Harmony,
ClassPath), 2.5 million lines of code
• Found 20 new, exploitable security
vulnerabilities across all 3 implementations
– Example: security check is present, but inside a
privileged section of library code (very subtle!)
– Many vulnerabilities found in code that was
previously analyzed with other techniques!
slide 51
More semantic vulnerabilities
• Modern servers have to deal with untrusted
network inputs
• Software defects open the door to denial-ofservice attacks via resource exhaustion
slide 52
Denial of service
• Flooding
– Target inundated with large number of requests
– Example: DDoS via botnet
• Nuking
– Malicious inputs exploit software bugs to crash
program (e.g., via memory corruption)
– Example: “ping of death”
• Resource exhaustion
– Example: algorithmic-complexity attacks
slide 53
wu-ftpd
• FTP server
• Uses regular expression pattern matching in
command arguments
– E.g. DIR * results in tecs11.aux
tecs11.bib
tecs11.pdf
tecs11.tex
tecs11.aux
tecs11.bib
tecs11.pdf
tecs11.tex
slide 54
wu-ftpd vulnerability
• DIR **************** results in100% CPU
utilization for several minutes
– Discovered in 2005, then patched
• We call such attack inputs “inputs of coma”
• Does not require multiple requests
• Does not exploit a violation of language
semantics!
– Unlike “inputs of death”
slide 55
wu-ftpd vulnerability
static int amatch(char *s, char *p) {
for (;;) {
switch (c = *p++) {
pattern
string
case ‘{’:
return execbrc(p-1,s-1);
…
case ‘*’:
if (!*p)
return 1;
do {
if (amatch(s, p))
return 1;
} while (*s++);
exploitable recursive call
return 0;
}
Attack string DIR ********* causes
}
exponential number of recursive calls
}
slide 56
Resource-exhaustion attacks
•
•
•
•
•
•
Web servers (IIS)
Virus scanners (Windows Defender, ClamAV)
DNS proxy servers (DNRD)
Samba
PHP (Zend engine, PHPMailer)
XML parsers (libxml2, “billion laughs” attack)
<!DOCTYPE root [
<!ENTITY ha "Ha !">
<!ENTITY ha2 "&ha; &ha;">
...
<!ENTITY ha128 "&ha127;&ha127;"> ]>
<root>&ha128;</root>
slide 57
Challenges
• Attacks exploit semantics of target code
– Design flaws vs. programming bugs
– Vulnerable wu-ftpd code “works” – it matches
patterns correctly!
• Often launched with single request, rarely
associated with network traffic anomalies
• Don’t violate programming language semantics,
memory safety, control-flow integrity…
• Difficult to detect with conventional methods
slide 58
CPU and stack exhaustion
• What is the “essence” of these attacks?
• Small user input triggers “complex” execution
• Complex = super-linear in the size of the input
– Example (wu-ftpd): malicious pattern of length n
causes server to execute exponential number of
recursive calls to amatch()
slide 59
SAFER
• SAFER: Static Analysis Framework for
Exhaustion of Resources
– C programs, currently extending to PHP
• Identify program statements whose execution
is influenced by untrusted network inputs
– Control dependency + taint analysis
• Resource-specific analyses detect highcomplexity control structures whose
execution influenced by inputs
slide 60
SAFER architecture
slide 61
Control dependencies
• Informally, CFG node A is control-dependent
on another CFG node B if whether A is
executed depends on the execution of a
conditional statement at B
– Control dependencies between statements follow
directly from node relations
• Classic intra-procedural analysis based on
post-dominance relation
slide 62
Control dependencies: example
static int amatch(char *s, char *p) {
for (;;) {
switch (c = *p++) {
case ‘{’:
return execbrc(p-1,s-1);
…
case ‘*’:
if (!*p)
return 1;
do {
if (amatch(s, p))
return 1;
} while (*s++);
return 0;
}
}
}
slide 63
Taint analysis
• Computes set of program variables that are
data-dependent on user input
– User input = result of a call to a source tainting
function (e.g., socket)
• X is data-dependent on Y at a program
location if and only if the current value of X is
due to an assignment x := e, such that e is an
expression containing Y, or some other
variable Z that is data-dependent on Y
slide 64
Two-phase taint analysis
• Bottom-up procedure summarization
– For each procedure p, compute a summary of p
which summarizes the effect of calling p on the
taint label of globals and passed arguments
– For library calls, use user-defined summaries
• Top-down taint computation
– Fixed-point dataflow analysis computes taint label
for all live variables at each program location
– When a procedure call is reached, apply summary
slide 65
Taint analysis: example
Summary of accept()
sock → return
Summary of read()
i → buf
i → return
int i = accept(sock, addr, *addrlen);
n = read(i, buf, count);
char c = *buf;
slide 66
Taint analysis: wu-ftpd example
static int amatch(char *s, char *p) {
for (;;) {
switch (c = *p++) {
case ‘{’:
return execbrc(p-1,s-1);
…
case ‘*’:
if (!*p)
return 1;
do {
if (amatch(s, p))
return 1;
} while (*s++);
return 0;
}
}
}
slide 67
Putting it all together
• Recall: wu-ftpd attack causes program to
execute path that leads to resource exhaustion
• Tainted values do not flow into critical function
call (unlike SQL injection and cross-site
scripting)
• Expensive recursive call is control-dependent
on statement that uses tainted values
slide 68
SAFER analysis
• Identify loops and recursive calls that are controldependent on tainted statements
• For loops, examine all edges leaving loop body, check
if target of edge is control-dependent on tainted
statement - these are tainted loops
• For calls, compute context-sensitive call graph, for all
recursive calls check if call is control-dependent on
tainted statements – these are tainted recursive calls
– Bound context depth for efficiency
• Estimate complexity of recursion (heuristic)
slide 69
Example (wu-ftpd)
static int amatch(char *s, char *p) {
for (;;) {
switch (c = *p++) {
case ‘{’:
return execbrc(p-1,s-1);
…
case ‘*’:
if (!*p)
return 1;
Tainted loop do {
if (amatch(s, p))
Tainted recursive call
return 1;
} while (*s++);
return 0;
}
}
}
slide 70
Scalability
• Analyzed programs with over 100,000 LOC
• Low false positive rate
– 7 warnings for 109,000 LOC in Apache
• Warnings inform developers that expensive
computation can be triggered by remote users
• Tradeoffs and limitations
– Imprecision of taint analysis (field-insensitive)
– Sanitization
– Function pointers
slide 71
wu-ftpd Vulnerability (again)
• Original attack discovered in 2005
– Patch issued to address vulnerability
– Collapse contiguous blocks of *’s prior to call
• SAFER’s context-sensitive recursive call analysis
reports 2 contexts in which recursive call is
control-dependent on tainted statements
Call funcName: amatch, file: glob.c, line: 448
Recursive calling contexts:
1) [match:glob.c:280, amatch:glob.c:395, ]Original attack
2)[execbrc:glob.c:240, amatch:glob.c:366, ]
New attack
slide 72
New wu-ftpd attack
• Attack command: DIR *{*{*{*{*{…}*}*}*}*}*
– 100% CPU utilization for several minutes
– Attack works against latest patched version
– Patch “sanitizes” input prior to amatch() call in
only one context. After *’s are collapsed, pattern is
passed to execbrc() which removes {}’s and calls
amatch() with pattern of contiguous *’s.
• Lesson: understand root causes of attacks, not
just block known exploits
slide 73
Expat vulnerability
• Stream-oriented XML parsing library
• Used in PHP, Python, Perl implementations
• Stack exhausted by arbitrarily deep recursive
calls while parsing DTDs
• 800kb DTD crashes target application via
stack exhaustion
<!ELEMENT A (A,(A,(A,(A,(A,(A,(A,
(A,(A,(A,(A,(A,(A,(A,(A,(A,(A,(A,
(A,(A,(A,(A,(A,(A,(A,(A,(A,(A,(A,...
slide 74
SQLite vulnerability
• Query with deeply nested SELECT clauses
causes huge temporary results to be generated
– SELECT * FROM (SELECT * FROM (…) as t1) as t2
JOIN SELECT * FROM (…
• Result set with 264 rows if DB contains a single
table with 2 rows, iterating over set causes
100% CPU utilization for several minutes
• Attacker must control query string
– … could work in combination with SQL injection
slide 75
More reading
• Chang et al. “Inputs of Coma: Static
Detection of Denial-of-Service
Vulnerabilities” (CSF 2009)
slide 76
Attacker-controlled infinite loops
• Termination of a loop in the code depends on
the value of some tainted variable
– Sophisticated analysis (tainting + symbolic
execution) to find these vulnerabilities
• PHP example (from simplehtmldom)
function restore_noise($text) {
while(($pos=strpos($text, ’___noise___’))!==false) {
$key = ’___noise___’.$text[$pos+11].
$text[$pos+12].$text[$pos+13];
if (isset($this->noise[$key]))
$text = substr($text, 0, $pos). $this->noise[$key].substr($text, $pos+14);
}
If HTML attribute value contains substring
return $text; }
’___noise___’, this loop will never terminate
Other semantic vulnerabilities
• Missing authorization checks
• Unintended entry points
– Especially common in PHP applications since they
consist of multiple files
– Each file is a potential entry point, may introduce
execution paths bypassing authorization checks
• Challenge: how to recognize code performing
authorization checks?
slide 78
Summary
• Shift from “unsafe” (C, C++) to “safe”
programming languages (Java, PHP)
• Fewer memory-corruption exploits, increasing
severity of semantic attacks
– Missing security checks and misconfigured policies
– Denial of service due to badly written code
– SQL injection and cross-site scripting
• Semantic vulnerabilities are poorly understood
and hard to find
slide 79