The Invisible Mitigatory Controls Vulnerability Report By Daniel de Jager
TABLE OF CONTENTS
TABLE OF CONTENTS .................................................................................................. 2 Introduction ..................................................................................................................... 4 Stack based Buffer Overflows ......................................................................................... 4 Background ..................................................................................................................... 4 Program Structure ........................................................................................................... 5 The vulnerability: CVE-2010-4221 .................................................................................. 6 FTP and Telnet IAC......................................................................................................... 7 Vulnerability Analysis ...................................................................................................... 7 Vulnerability Testing ........................................................................................................ 9 Countermeasures Identified and Overview ..................................................................... 9 Forcing the check of buflen == 0 ................................................................................... 10 Stack Smash Protection ................................................................................................ 11 Comparison of Countermeasures ................................................................................. 11 Description of Application of Chosen Countermeasure ................................................. 12 Contribution: Critique of Chosen Countermeasure ........................................................ 12 Conclusion .................................................................................................................... 13 Appendix A – Vulnerabilities Distribution (CVE Details, 2015) ...................................... 15 Appendix B – NETIO.C ................................................................................................. 16 Appendix C – Configuration and Exploit without STACK PROTECTION ...................... 20 Appendix D – Results of Countermeasures implemented ............................................. 22 Appendix E – Shodan.io search for ProFTPd 1.3.3a ..................................................... 25 References .................................................................................................................... 26
Figure 1 Process Memory ............................................................................................... 5 Page 2 of 27
Figure 2 Logical Stack Area ............................................................................................ 5 Figure 3 Overflowed Buffer and Stack............................................................................. 6 Figure 4 FTP Model......................................................................................................... 7 Figure 5 Stack Protection through Stack Guard ............................................................ 11 Figure 6 Removing Wstack-protector CC Flags ............................................................ 20 Figure 7 Removing fstack-protector flags ...................................................................... 20 Figure 8 Metasploit TELNET IAC Exploit ...................................................................... 21 Figure 9 Resulting Signal 11 Error i.e. Segmentation Fault........................................... 21
Page 3 of 27
Introduction
This paper is explores Common Vulnerability Enumeration (CVE) 2010-4221, which is a description of a buffer overflow flaw present in a Linux FTP program called ProFTPd version 1.3.3a. This is still a current vulnerability and issue since a recent Shodan report showed 39, 068 ProFTPd 1.3.3a servers live on the internet. The results of a screen capture are shown in Appendix E. We explore the concept of a buffer overflow which after I will explain where it can be found in the actual software. Since it is our goal to identify, test and compare countermeasures against the exploitation of the vulnerability, we will explore stack smash protection mechanisms as provided by the GCC compiler, as well as the actual code to fix the vulnerability present in version 1.3.3a of ProFTPd. In the last section we describe some flaws present in the chosen countermeasure as it pertains to this project of this course and then lastly present a conclusion in the final section.
Stack based Buffer Overflows
Background
Buffer Overflows has been a considerable threat to the Confidentiality, Integrity and Availability of Information Systems for a long time. In their paper “Buffer Overflows: Attacks and defenses for the vulnerability of the decade� by Cowan, Wagle, Pu and Beattie (2000), they explain that if buffer overflow vulnerabilities are eliminated, that a very large amount of security threats would be in general also be eliminated.
This is contrast to current statistics on recorded vulnerabilities in the National Vulnerability Database as from September 2015. 14.3% of vulnerabilities are as a direct result of overflow vulnerabilities. Denial of service and Code Execution are still the dominant vulnerabilities to date (CVE Details, 2015). In actual fact, overflow vulnerabilities appears to be doubling in count each year, peaking at 2719 in 2006 and
Page 4 of 27
then declining to 1254 gradually towards 2015. It is therefore apparent that the problem of buffer overflow flaws in software is not one that is being eliminated.
Program Structure
In order to understand how a buffer overflow works, it is important to understand how a process is structured in working memory during execution time. A process is divided into three areas in memory, the text area, data area and then lastly the stack area, which is used for the storage of local variables during execution time, as depicted in Figure 1 (Bell, 2015).
Anonymous-1 (1996), presented a paper on stack smashing in Phrack Magazine and how it works. For the purposes of this report, I will present a high level overview using code from C++.
Consider the following code: STACK void vulnerablefunction(int a, int b) { char buffer[15]; }
HEAP
int main() { vulnerablefunction(1,2); return 0; }
DATA TEXT Figure 1 Process Memory
When the code snippet above is executed, it will create a stack area similar to Figure 2 below. Each local variable is allocated memory space; a return address is reserved as well as the stack frame pointer, then lastly the buffer that has been declared in vulnerablefunction. buffer
Figure 2 Logical Stack Area
Page 5 of 27
SFP
RET
a
b
The buffer in Figure 2, grows to the right, in other words to higher memory spaces. In order to cause a buffer overflow, more data than what is being allocated, 15 bytes, must be stored in buffer. This would cause SFP, RET, a and b to be overwritten. The next code section explains how the buffer is overflowed: void vulnerablefunction(char *long_string) { char buffer[15]; strcpy(buffer, long_string) } int main() { char array[256]; for(int i=0; i <= 255; i++) { array[i] = 'Z' } vulnerablefunction(array); return 0; }
The hex value of ‘Z’ is 5A. This value is stored in array and then passed to long_str as a parameter to function vulnerablefunction. The buffer grows beyond its 15 bytes and overwrites the memory values in the control area i.e. all other parameters stored in the stack. What is important to note, is that the return address value will also now be 0x5A5A5A5A, which is then used by the attacker to execute his own “arbitrary” code, normally to gain administrative access through a command shell.
Successful stack buffer overflow results in a signal 11 fault under GCC which is a segmentation error. 5A
5A
5A
5A
5A
Figure 3 Overflowed Buffer and Stack
The vulnerability: CVE-2010-4221
NVD (2015) described a stack-based buffer overflow in a function within ProFTPd present in the pr_netio_telnet_gets function in netio.c specifically for version 1.3.3a, that allows attackers to execute arbitrary code via vectors involving a telnet IAC character to
Page 6 of 27
a FTP or FTPS server. The Common Vulnerability Scoring System (CVSS) base score has been calculated as 10, and the vector is as follows: (AV:N/AC:L/Au:N/C:C/I:C/A:C). The vector indicates that the vulnerability can be exploited remotely without difficulty and without authentication, in order to gain root access to the server. Let us review the File Transport Protocol (FTP) and Telnet Interpret as Command (IAC) before we review the pr_netio_telnet_gets function in ProFTPd.
FTP and Telnet IAC
The File Transfer Protocol is defined in RC959, by the Network Working Group. The FTP model shows that a low port is normally used for FTP Commands and Replies and a High Port is used for Data Connections (RFC-1, 1985).
Figure 4 shows the FTP
model.
TCP Port 21 FTP
FTP Requests FTP Replies
Server
FTP Client
Data High
TCP
Figure 4 FTP Model
Telnet, as defined by RFC854, provides a two-way communication system. Interpret as Command (IAC) bytes are special bytes between to clients running telnet in order to assist in the communication process. When a command is sent from one host to the other, a â&#x20AC;&#x153;255â&#x20AC;? IAC is sent directly after the command which tells the receiving host that the command must be interpreted as a command and not text (RFC-2, 1983).
Vulnerability Analysis
Page 7 of 27
I have installed ProFTPd 1.3.3a on Linux 3.18 Debian and have taken a white box testing approach in order to understand the code behind the vulnerability, and using Metasploit as a testing tool. If in any circumstance, a Segment 11 fault is triggered, then the exploit caused a buffer overflow. ProFTPd receives an incoming stream using the PR_NETIO_TELNET_GETS() function in Main.c as seen below into a static buffer called PR_DEFAULT_CMD_BUFDZ + 1 int pr_cmd_read(cmd_rec **res) { static long cmd_bufsz = -1; char buf[PR_DEFAULT_CMD_BUFSZ+1] = {'\0'}; char *cp; size_t buflen; if (res == NULL) { errno = EINVAL; return -1; } while (TRUE) { pr_signals_handle(); memset(buf, '\0', sizeof(buf)); if (pr_netio_telnet_gets(buf, sizeof(buf)-1, session.c->instrm, session.c->outstrm) == NULL) {
When iterating through the PR_NETIO_TELNET_GETS() function in netio.c, the following code becomes apparent: while (buflen && toread > 0 && *pbuf->current != '\n' && toread--) { cp = *pbuf->current++; pbuf->remaining++;
*bp++ = TELNET_IAC; buflen--;
Decremented twice. telnet_mode = 0; break;
While
}
check
bypassed
*bp++ = cp; buflen--; }
Page 8 of 27
is
The issue seen above is when buflen == 1; the code will decrement buflen twice resulting in a non-positive integer, the root cause of the bug that is exploitable (Anonymous-2, 2010).
Vulnerability Testing
In order to invoke the segmentation fault without any protection mechanisms, it was necessary to customize the configuration file of ProFTPd, removing C++ flags which enable STACK SMASH PROTECTION, after which ProFTPd is compiled in GCC version 4.7.
Appendix C shows the altered configuration, the Metasploit exploit
configuration, and the result of testing, which led to a Signal 11 fault indicative of a Segmentation Fault.
Countermeasures Identified and Overview
Based on the research performed two countermeasures has been prepared for this report. The first, as indicated in the proposal, was to remedy the code issue present in netio.c by making the necessary changes to detect when buflen = 0, and then taking preventative measures before buflen is decremented again.
The second approach is less pro-active, but presents a detective control without making any code changes, in the form of stack smash protection. The same Metasploit testing module was used in both cases.
The next section will describe each countermeasure. Appendix D shows the results of testing when the counter measures where implemented.
Page 9 of 27
Forcing the check of buflen == 0
Since special crafted Telnet IAC commands are used to ensure that the while loop checks out to be true, it forces buflen to become 1, after which it is decremented twice and the check to determine if buflen == 0 is bypassed.
Two options for checking whether checking buflen == 0 was tested. Firstly, altering the main while loop and adding an operator to check whether buflen > 1. The code is shown below: while (buflen > 1 && toread > 0 && *pbuf->current != '\n' && toread--) { cp = *pbuf->current++; pbuf->remaining++;
Multiple exploits has been tested against ProFTPd, with no signal 11 failures. However, based on the output, it seems that the FTP sessions do not get closed and results of testing are inconclusive since this approach might cause a Denial-of-Service (DoS). This is not ideal since Availability is paramount.
The second test included adding an if statement, just before the second decrementation of buflen, as a safer check since we did not alter the main while loop, but added only an additional check. The code is shown below: if (buflen == 0) { break; } *bp++ = cp; buflen--;
This result in the same behaviour as described above, however, FTP sessions are closed.
Page 10 of 27
Stack Smash Protection
Stack Guard is a detective control that is implemented through the GCC compiler, by adding a guard (â&#x20AC;&#x153;Canaryâ&#x20AC;?) value to the stack. The canary is inserted before the protected area after the Stack Frame Pointer (SFP), Return Address (RET) and local variables are set and it is verified before the local variables and control values are restored. If there is a change in the value of the canary, then a stack smash attempt occurred (Wagle & Cowan, 2003). buffer
CANARY
SFP
RET
a
b
Figure 5 Stack Protection through Stack Guard
The goal of the exploitation code is to redirect the flow of execution to shellcode the attacker has written in order to be executed to provide administrative or root access. During this process, the canary value will be overwritten, and when checked by the compiler, it will be noted that the canary value changed and the process will terminate.
Comparison of Countermeasures
Making code changes versus enabling a security feature of GCC are two methods that are far apart. The code changes requires one to perform an in depth white box testing methodology using the correct development, compilation and documentation tools. It is far more time consuming than what enabling a compiler security control would be. However, it completely eliminates the signal 11 error and the application functions as per normal.
Stack Smash Protection on the other hand is a detective control as mentioned and the stack trace logs can be put to use by operations personnel in the monitoring center through the use of log collection. It is even possible to monitor the stack smashing during its operation in nearly real-time through the use of SIEM technology.
Page 11 of 27
Description of Application of Chosen Countermeasure
Since many organisations to not have the resources, capacity or skill to incorporate penetration testing as part of the software development lifecycle, it makes sense to recommend stack smashing protection as a feasible yet effective detective control.
Since stack protection is implemented in many different ways, it is not a mediocre task to bypass stack protection easily. There are, in certain cases, scenarios where this can be achieved through information leaking which will be described in the next section, since throughout this paper I eluded to the fact that stack protection is only a detective control in the hands of a well experienced exploit developer, and not a complete and secure preventative control to implement.
Contribution: Critique of Chosen Countermeasure
According to Anonymous-3 (2000) where there is a will there is way to bypass stack protection mechanisms such as stackguard and stackshield. The following provides a list of bypassing techniques:
1. It is not always necessary to re-write the return address. Other pointers can be used, even those not present on the stack. 2. Data Segment based overflows can break stack protection. 3. Techniques can be used to overwrite other pointers without touching the canary. 4. Code can be written to exploit on the exit() command address. 5. Code can be written to exploit the GOT entry of another calling function.
What is required on behalf of the programmer writing the exploit is only good C++ skills and disassembly tool knowledge in order to determine the addresses of pointers in memory.
Page 12 of 27
Strackx, Younan and Philippaerts (2009), refers to modern stack protection mechanisms as probabilistic countermeasures. Their work shows that:
1. Assumptions leave probabilistic countermeasures vulnerable. 2. There is a lack of proper encryption applied to protect key values.
They predict that even having a combination of protection mechanisms in the class of probabilistic countermeasures that exploits bypassing these protections are feasible and may become increasingly common going forward.
Conclusion
It became apparent writing this report and performing the testing on proftpd, that there exists a cat and mouse game between application developers, security developers and exploit developers, almost like a game of chess, as it seems for every move there is a counter move.
My opinion is as follows: Security Testing should not be a nice to have in the software development lifecycle, it should be mandatory since we have shown simple it is to disassemble code, read memory addresses and run exploit tools; especially in the open source domain. Tight controls around release planning should be performed given a certain level of assurance by penetration testers. This really comes down to good Security Governance Practices.
What is more apparent during the vulnerability assessment phase of this project is the fact that â&#x20AC;&#x153;invisibleâ&#x20AC;? security controls do exist on the compiler level. It is quite easy to assume that a software is vulnerable without having visibility into the actual configuration of the software, realising only later that the time spent remediating and the associated cost was completely unnecessary. Therefore, in the case of his vulnerability, mitigation was already implemented and the severity of the vulnerability could have been decreased from a critical, to a low. Page 13 of 27
Lastly, from an education point of view, it is critical that programming students become familiar with the concepts of exploits and counter measures and immerse themselves in the secure programming of their computer languages and inherently apply these skillsets in the work place and to be familiar with the security controls implemented in the core language. There is certainly much more room for improvement given the vulnerabilities listed in Appendix A, agreeing that the human programmer is the root cause of assumptive programming, giving rise to vulnerabilities.
However, a fundamental understanding of the vulnerability management process is mandatory in the workplace, and involvement in the vulnerability management process. It is therefore recommended that vulnerability management practitioners extend the vulnerability management program into the software development space in order to manage vulnerabilities holistically.
Page 14 of 27
Appendix A â&#x20AC;&#x201C; Vulnerabilities Distribution (CVE Details, 2015) # of Y ear
V ulnerabil
DoS
ities
1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 Total % Of All
894 1020 1677 2156 1526 2450 4934 6610 6520 5632 5736 4651 4155 5297 5191 7946 4757 71152
Code Exec ution
Overflow
177 257 402 497 381 580 838 893 1100 894 1035 1102 1221 1425 1453 1597 1275 15127
112 207 402 553 476 614 1625 2719 2601 2310 2184 1714 1334 1457 1186 1573 1254 22321
172 206 297 435 370 409 653 662 952 699 700 677 770 844 859 847 657 10209
21.3
31.4
14.3
Memory
Sql
Corruption Injec tion
X SS
Direc tory Traversal
2 2 3 21 91 95 128 188 342 351 423 366 420 489 2921
2 7 41 49 148 604 967 706 1101 963 520 294 242 155 304 179 6282
2 4 34 200 129 291 786 1302 883 807 851 605 467 758 650 1107 649 9525
7 20 123 103 60 110 202 321 339 363 322 275 108 122 110 204 116 2905
4.1
8.8
13.4
4.1
Page 15 of 27
Http Response Splitting
Bypass something
Gain Informatio n
Gain Privileges
CSRF
File
# of
Inc lusion
exploits
1 12 15 8 14 7 9 8 7 13 7 12 8 121
25 48 83 127 61 145 289 267 267 288 338 234 197 343 350 457 397 3916
13 19 35 74 69 96 261 267 322 270 302 282 409 389 510 2104 526 5948
102 138 219 199 144 134 221 184 242 188 223 237 206 250 274 239 250 3450
5 11 18 69 83 115 86 58 166 123 264 208 1208
2 14 16 38 100 849 700 170 138 73 17 14 1 2 4 2138
0.2
5.5
8.4
4.8
1.7
3
2
2
2 2 8 13 25 97 1251 1936 2108 1469 564 615 202 391 118 8803
Appendix B â&#x20AC;&#x201C; NETIO.C char *pr_netio_telnet_gets(char *buf, size_t buflen, pr_netio_stream_t *in_nstrm, pr_netio_stream_t *out_nstrm) { char *bp = buf; unsigned char cp; int toread, handle_iac = TRUE, saw_newline = FALSE; pr_buffer_t *pbuf = NULL; if (buflen == 0) { errno = EINVAL; return NULL; } #ifdef PR_USE_NLS handle_iac = pr_encode_supports_telnet_iac(); #endif /* PR_USE_NLS */ buflen--; if (in_nstrm->strm_buf) pbuf = in_nstrm->strm_buf; else pbuf = netio_buffer_alloc(in_nstrm); while (buflen) { /* Is the buffer empty? */ if (!pbuf->current || pbuf->remaining == pbuf->buflen) { toread = pr_netio_read(in_nstrm, pbuf->buf, (buflen < pbuf->buflen ? buflen : pbuf->buflen), 1); if (toread <= 0) { if (bp != buf) { *bp = '\0'; return buf; } else { return NULL; } } pbuf->remaining = pbuf->buflen - toread; pbuf->current = pbuf->buf; } else toread = pbuf->buflen - pbuf->remaining; while (buflen && toread > 0 && *pbuf->current != '\n' && toread--) { cp = *pbuf->current++; pbuf->remaining++; if (handle_iac == TRUE) { switch (telnet_mode) { case TELNET_IAC: switch (cp) { case TELNET_WILL:
Page 16 of 27
case TELNET_WONT: case case case case
TELNET_DO: TELNET_DONT: TELNET_IP: TELNET_DM:
/* Why do we do this crazy thing where we set the "telnet mode" * to be the action, and let the while loop, on the next pass, * handle that action?
It's because we don't know, right
now, * whether there actually a "next byte" in the input buffer. * There _should_ be -- but we can't be sure. And that next * byte is needed for properly responding with WONT/DONT * responses. */ telnet_mode = cp; continue; default: /* In this case, we know that the previous byte was TELNET_IAC, * but the current byte is not a value we care about. So * write the TELNET_IAC into the output buffer, break out of * of the switch, and let that handle the writing of the * current byte into the output buffer. */ *bp++ = TELNET_IAC; buflen--; telnet_mode = 0; break; } break; case TELNET_WILL: case TELNET_WONT: pr_netio_printf(out_nstrm, "%c%c%c", TELNET_IAC, TELNET_DONT, cp); telnet_mode = 0; continue; case TELNET_DO: case TELNET_DONT: pr_netio_printf(out_nstrm, "%c%c%c", TELNET_IAC, TELNET_WONT, cp); telnet_mode = 0; continue; case TELNET_IP: case TELNET_DM: default: if (cp == TELNET_IAC) { telnet_mode = cp; continue; }
Page 17 of 27
break; } } *bp++ = cp; buflen--; } if (buflen && toread && *pbuf->current == '\n') { buflen--; toread--; *bp++ = *pbuf->current++; pbuf->remaining++; saw_newline = TRUE; break; } if (!toread) pbuf->current = NULL; } if (!saw_newline) { /* If we haven't seen a newline, then assume the client is deliberately * sending a too-long command, trying to exploit buffer sizes and make * the server make some possibly bad assumptions. */ properly_terminated_prev_command = FALSE; errno = E2BIG; return NULL; } if (!properly_terminated_prev_command) { properly_terminated_prev_command = TRUE; pr_log_pri(PR_LOG_NOTICE, "client sent too-long command, ignoring"); errno = E2BIG; return NULL; } properly_terminated_prev_command = TRUE; *bp = '\0'; return buf; } int pr_register_netio(pr_netio_t *netio, int strm_types) { if (!netio) { pr_netio_t *core_netio = NULL; /* Only instantiate the core NetIO objects once, reusing the same pointer. */ if (!core_ctrl_netio) core_netio = core_ctrl_netio = pr_alloc_netio(permanent_pool); if (!core_data_netio)
Page 18 of 27
errno = EINVAL; return NULL; } netio_pool = make_sub_pool(parent_pool); /* If this is the daemon process, we are allocating a sub-pool from the * permanent_pool. You might wonder why the daemon process needs netio * objects. It doesn't, really -- but it's for use by all of the session * processes that will be forked. They will be able to reuse the memory * already allocated for the main ctrl/data/other netios, as is. * * This being the case, we should label the sub-pool accordingly. */ if (mpid == getpid()) { pr_pool_tag(netio_pool, "Shared Netio Pool"); } else { pr_pool_tag(netio_pool, "netio pool"); } netio = pcalloc(netio_pool, sizeof(pr_netio_t)); netio->pool = netio_pool; /* Set the default NetIO handlers to the core handlers. */ netio->abort = core_netio_abort_cb; netio->close = core_netio_close_cb; netio->open = core_netio_open_cb; netio->poll = core_netio_poll_cb; netio->postopen = core_netio_postopen_cb; netio->read = core_netio_read_cb; netio->reopen = core_netio_reopen_cb; netio->shutdown = core_netio_shutdown_cb; netio->write = core_netio_write_cb; return netio; }
Page 19 of 27
Appendix C â&#x20AC;&#x201C; Configuration and Exploit without STACK PROTECTION
Figure 6 Removing Wstack-protector CC Flags
Figure 7 Removing fstack-protector flags
Page 20 of 27
Figure 8 Metasploit TELNET IAC Exploit
Figure 9 Resulting Signal 11 Error i.e. Segmentation Fault
Page 21 of 27
Appendix D – Results of Countermeasures implemented
CODE CHANGES: Using if statement to check when BUFLEN == 0 (WITHOUT STACK_SMASH_PROTECTION)
CODE CHANGES: BUFLEN == 0 (WITH STACK_SMASH_PROTECTION)
Page 22 of 27
Code changes in the while loop, checking whether while buflen > 1(WITH STACK_SMASH_PROTECTION)
NOTE: The FTP Session is opened, but never closed, which may result in a FTP flood resulting in a Denial-of-Service condition. The proftpd configuration file can limit the amount of connections through a set integer.
Page 23 of 27
Configurations file to enable STACK SMASH Protector
Page 24 of 27
Appendix E â&#x20AC;&#x201C; Shodan.io search for ProFTPd 1.3.3a
A Shodan search shows 39, 068 instances of proftpd version 1.3.3a that has been recorded.
Page 25 of 27
References
[1]
Anonymous-1, (1996). Smashing the Stack for Fun and Profit, Phrack Magazine, Available
Online: http://phrack.org/issues/49/14.html. Accessed: 1 September
2015.
[2]
Anonymous-2, (2010). CVE-2010-4221: ProFTPd TELNET_IAC Remote Stack Overflow.
Available online:[ https://xorl.wordpress.com/2010/11/15/cve-2010-
4221-proftpd-telnet_iac-remote-stack-overflow/]. Accessed: 11 September 2015.
[3]
Anonymous-3, 2000. Bypassing Stackguard and Stackshield. Phrack Magazine, Volume 0x05, Issue 0x38. Available online:[http://Phrack.org/issues/56/5.html]. Accessed: 20 September 2015.
[4]
Bell, J., (2015). Computer Science Course Notes, Operating Systems, University of
Illinois, Department of Computer Science. Available online from:
[http://www.cs.uic.edu/~jbell/CourseNotes/OperatingSystems/3_Processes.html]. Accessed: 20 September 2015.
[5]
Cowan, C., Wagle, P., Pu, C., Beattie, S., & Walpole, J. (2000). Buffer overflows: Attacks and defenses for the vulnerability of the decade. In DARPA Information Survivability Conference and
Exposition,
2000.
DISCEX'00.
Proceedings (Vol. 2, pp. 119-129). IEEE.
[6]
CVE
Details,
(2015),
Vulnerabilities
by
Type.
Available
Online:
[http://www.cvedetails.com/vulnerabilities-by-types.php]. Accessed: 5 September 2015
Page 26 of 27
[7]
NVD. National Vulnerability Database. Vulnerability Summary for CVE-20104221. Available online: [https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE2010-4221]. Accessed: 6 September 2015.
[8]
RFC-1, (1985). Network Working Group. File Transfer Protocol. Available online:[ https://www.ietf.org/rfc/rfc959.txt]. Accessed: 10 September 2015.
[9]
RFC-2, (1983). Networking Working Group. Telnet Protocol Specification. Available online: [https://tools.ietf.org/html/rfc854]. Accessed: 10 September 2015.
[10]
Richarte, G., (2002). Four different tricks to bypass stackshield and stackguard protection.
Available
online:
[http://www.coresecurity.com/files/attachments/StackGuard.pdf]. Accessed: 15 September 2015.
[11]
Wagle, P., & Cowan, C., (2003). Stackguard: Simple stack smash protection for gcc. In Proceedings of the GCC Developers Summit (pp. 243-255).
[12]
Strackx, R., Youman, Y., Philippaerts, P., (2009). Breaking the memory secrecy assumption. In EUROSEC â&#x20AC;&#x2122;09: Proceedings of the Second European Workshop on System Security. ACM Digital. Pp1-8.
Page 27 of 27