Memory corruption (e.g., buffer overflows, random writes, memory
allocation bugs, or uncontrolled format strings) is one of the oldest
and most exploited problems in computer science. Low-level languages
like C or C++ trade memory safety and type safety for performance: the
compiler adds no bound checks and no type checks. The programmer itself
is responsible for memory management and type casting which can lead to
serious exploitable bugs. Prerequisites for a successful memory
corruption are (i) that a pointer is pushed out of bounds (i.e., by
iterating over the end of a buffer) or that a pointer becomes dangling
(i.e., by freeing the object that a pointer points to) and (ii) that the
attacker controls the value written to the out of bounds pointer, e.g.,
directly through an assignment or indirectly through some management
function.
Figure 1: development of different classes of memory corruption attacks;
based on CVE data.
On the other hand if we look at the development of memory corruption
attacks since 1999 (Figure 1) we see that the number of these attacks
rose until 2007 and is on an all-time high. So we can ask ourselves:
what went wrong? On one hand there are new attack vectors (e.g.,
code-reuse attacks like Return Oriented Programming [39]) and safe
languages have (i) too much overhead, (ii) too much latency (languages
like Java do not support realtime execution because of stop-the-world
garbage collection), (iii) missing support for legacy code, (iv)
increased complexity, and (v) missing features like direct memory access
for low-level applications.
The goal of this post is to explain different forms of memory corruption
attacks and possible defenses that are deployed for current software
systems. We will see that attack vectors and defense mechanisms are
closely related and through this relation they evolve alongside. This
article extends existing surveys and summaries [20, 36] by (i) a
study that looks at the symbiosis between attacks and defenses and (ii)
an analysis that explains why certain defense mechanisms are used in
practice while other mechanisms never see wide adoption.
References
[1] Abadi, M., Budiu, M., Erlingsson, U., and Ligatti, J. Control-flow
integrity. In CCS'05.
[2] Acharya, A., and Raje, M. MAPbox: using parameterized behavior
classes to confine untrusted applications. In SSYM'00: Proc. 9th Conf.
USENIX Security Symp. (2000), pp. 1--17.
[3] Aggarwal, A., and Jalote, P. Monitoring the security health of
software systems. In ISSRE'06: 17th Int'l Symp. Software Reliability
Engineering (nov. 2006), pp. 146 --158.
[4] Akritidis, P., Cadar, C., Raiciu, C., Costa, M., and Castro, M.
Preventing memory error exploits with WIT. In SP'08: Proc. 2008 IEEE
Symposium on Security and Privacy (2008), pp. 263--277.
[5] Aleph1. Smashing the stack for fun and profit. Phrack 7, 49 (Nov.
1996).
[6] Baratloo, A., Singh, N., and Tsai, T. Transparent run-time defense
against stack smashing attacks. In Proc. Usenix ATC (2000), pp.
251--262.
[7] Barrantes, E. G., Ackley, D. H., Forrest, S., and Stefanovi, D.
Randomized instruction set emulation. ACM Transactions on Information
System Security 8 (2005), 3--40.
[8] Bauer, M. Paranoid penguin: an introduction to Novell AppArmor.
Linux J. 2006, 148 (2006), 13.
[9] blackngel.The house of lore: Reloaded. Phrack 14, 67 (Nov.
2010).
[10] Bletsch, T., Jiang, X., Freeh, V. W., and Liang, Z. Jump-oriented
programming: a new class of code-reuse attack. In ASIACCS'11: Proc. 6th
ACM Symp. on Information, Computer and Communications Security (2011),
pp. 30--40.
[11] Bulba, and Kil3r. Bypassing stackguard and stackshield. Phrack
10, 56 (Nov. 2000).
[12] Checkoway, S., Davi, L., Dmitrienko, A., Sadeghi, A.-R., Shacham,
H., and Winandy, M. Return-oriented programming without returns. In
CCS'10: Proceedings of CCS 2010 (2010), A. Keromytis and V. Shmatikov,
Eds., ACM Press, pp. 559--572.
[13] Chen, P., Xing, X., Mao, B., Xie, L., Shen, X., and Yin, X.
Automatic construction of jump-oriented programming shellcode (on the
x86). In ASIACCS'11: Proc. 6th ACM Symp. on Information, Computer and
Communications Security (2011), ACM, pp. 20--29.
[14] Conover, M.w00w00 on heap overflows.
[15] Cowan, C., Barringer, M., Beattie, S., Kroah-Hartman, G., Frantzen,
M., and Lokier, J. Formatguard: automatic protection from printf format
string vulnerabilities. In SSYM'01: Proc. 10th USENIX Security Symp.
(2001).
[16] Cowan, C., Beattie, S., Johansen, J., and Wagle, P. PointguardTM:
protecting pointers from buffer overflow vulnerabilities. In SSYM'03:
Proc. 12th USENIX Security Symp. (2003).
[17] Cowan, C., Pu, C., Maier, D., Hintony, H., Walpole, J., Bakke, P.,
Beattie, S., Grier, A., Wagle, P., and Zhang, Q. StackGuard: automatic
adaptive detection and prevention of buffer-overflow attacks. In
SSYM'98: Proc. 7th USENIX Security Symp. (1998).
[18] Designer, S. Return intolibc.
[19] Dowd, M., Spencer, C., Metha, N., Herath, N., and Flake, H.
Professional source code auditing, 2002.
[20] Erlingsson, U. Low-level software security: Attacks and defenses.
FOSAD'07: Foundations of security analysis and design (2007), 92--134.
[21] Erlingsson, U., Abadi, M., Vrable, M., Budiu, M., and Necula, G. C.
XFI: Software guards for system address spaces. In OSDI'06.
[22] Flake, H. Third generation exploitation, 2002.
[23] Haas, P. Advanced format string attacks, DEFCON 18 2010.
[24] Hiroaki, E., and Kunikazu, Y. ProPolice: Improved stack-smashing
attack detection. IPSJ SIG Notes (2001), 181--188.
[25] Kc, G. S., Keromytis, A. D., and Prevelakis, V. Countering
code-injection attacks with instruction-set randomization. In CCS'03:
Proc. 10th Conf. on Computer and Communications Security (2003), pp.
272--280.
[26] klog. The frame pointer overwrite. Phrack 9, 55 (Nov. 1999).
[27] McCamant, S., and Morrisett, G. Evaluating SFI for a CISC
architecture. In SSYM'06.
[28] Necula, G., Condit, J., Harren, M., McPeak, S., and Weimer, W.
CCured: Type-safe retrofitting of legacy software. vol. 27, ACM, pp.
477--526.
[29] Nergal. The advanced return-into-lib(c) exploits. Phrack 11, 58
(Nov. 2007).
[30] Newsham, T. Format string attacks, 2000.
[31] OWASP. Definition of format string attacks.
[32] PaX-Team. PaX ASLR (Address Space Layout Randomization), 2003.
[33] Payer, M. Too much pie is bad for performance. 2012.
[34] Payer, M., and Gross, T. R. Fine-grained user-space security
throughvirtualization. In VEE'11.
[35] Payer, M., and Gross, T. R. String oriented programming: When ASLR
is notenough. In Proc. 2nd Program Protection and Reverse Engineering
Workshop (2013).
[36] Pincus, J., and Baker, B. Beyond stack smashing: Recent advances in
exploiting buffer overruns. IEEE Security and Privacy 2 (2004), 20--27.
[37] Planet, C. A eulogy for format strings. Phrack 14, 67 (2010).
[38] Ratanaworabhan, P., Livshits, B., and Zorn, B. Nozzle: A defense
against heap-spraying code injection attacks. In Proceedings of the
Usenix Security Symposium (Aug. 2009).
[39] Shacham, H. The geometry of innocent flesh on the bone:
Return-into-libc without function calls (on the x86). In CCS'07: Proc.
14th Conf. on Computer and Communications Security (2007), pp. 552--561.
[40] Shacham, H., Page, M., Pfaff, B., Goh, E.-J., Modadugu, N., and
Boneh, D. On the effectiveness of address-space randomization. In
CCS'04: Proc. 11th Conf. Computer and Communications Security (2004),
pp. 298--307.
[41] SkyLined. Internet explorer iframe src&name parameter bof
remotecompromise, 2004.
[42] Sovarel, A. N., Evans, D., and Paul, N. Where's the FEEB? the
effectiveness of instruction set randomization. In SSYM'05: Proc. 14th
Conf. on USENIX Security Symposium (2005).
[43] List of Ubuntu programs built with PIE. March 2013.
[44] Ubuntu securityfeatures, May 2012.
[45] van de Ven, A., and Molnar, I. Exec shield. 2004.
[46] Wahbe, R., Lucco, S., Anderson, T. E., and Graham, S. L. Efficient
software-based fault isolation. In SOSP'93.