├── glossary ├── info ├── syllabus ├── w1 ├── 1_intro-to-security.pdf ├── 2_software-security.pdf ├── 3_course-overview.pdf ├── 4_buffer-overflow-intro.pdf ├── 5_memory-layout.pdf ├── 6_overflow-attack.pdf ├── 7_code-injection.pdf ├── 8_other-memory-attacks.pdf ├── 9_format-string-attacks.pdf ├── project-1 │ ├── info │ ├── wisdom-alt.c │ └── wisdom-alt_others_annotation.c ├── qualifying-quiz ├── vm-bof-quiz └── week-1-quiz ├── w2 ├── 1_memdefense-intro.pdf ├── 2_memory-safety.pdf ├── 3_type-safety.pdf ├── 4_avoiding-exploitation.pdf ├── 5_ROP.pdf ├── 6_CFI.pdf ├── 7_secure-coding.pdf └── week-2-quiz ├── w3 ├── 1_web-intro.pdf ├── 2_web-basics.pdf ├── 3_sql-injection.pdf ├── 4_sql-injection-countermeasures.pdf ├── 5_web-state.pdf ├── 6_session-hijacking.pdf ├── 7_CSRF.pdf ├── 8_web2.0.pdf ├── 9_XSS.pdf ├── badstore-quiz ├── project-2 │ ├── BadStore_net_v2_1_Manual.pdf │ └── info └── week-3-quiz ├── w4 ├── 1_secure-design-intro.pdf ├── 2_threat-modeling.pdf ├── 3_security-requirements.pdf ├── 4_design-flaws.pdf ├── 5_design-favor-simplicity.pdf ├── 6_design-trust-reluctantly.pdf ├── 7_design-did-mt.pdf ├── 8_top-design-flaws.pdf └── week-4-quiz ├── w5 ├── 1_static-analysis-intro.pdf ├── 2_static-analysis-overview.pdf ├── project-3-quiz ├── project-3-quiz1 ├── project-3 │ ├── info │ └── projects │ │ ├── 1 │ │ ├── runbin.sh │ │ ├── wisdom-alt │ │ └── wisdom-alt.c │ │ └── 3 │ │ ├── fuzz.py │ │ ├── fuzzinput │ │ ├── maze-sym.c │ │ ├── maze.c │ │ ├── wisdom-alt-sym.c │ │ ├── wisdom-alt.c │ │ └── wisdom-alt2.c └── week-5-quiz └── w6 ├── 1_pen-testing-intro.pdf ├── 2_pen-testing.pdf ├── 3_fuzzing.pdf └── week-6-quiz /glossary: -------------------------------------------------------------------------------- 1 | We use many technical terms in this course, and they might sometimes be hard to keep straight. As such, we will accumulate definitions of terms here each week. 2 | 3 | Next to each term, in parentheses, is the week during which the term was first used, in case you'd like to revisit lecture material to learn more about it. 4 | 5 | A 6 | 7 | • Abstraction (5) - With reference to a program's semantics, an abstraction is an approximation. All valid behaviors of the program are represented by the abstraction, but invalid ones may be too. 8 | 9 | • Abuse case (4) - A scenario that details a potential security failure if some defense is not put in place. Used during the design phase to motivate and justify security-related design decisions. 10 | 11 | • Access control (4) - A kind of security policy that governs what principals have access to resources, and what kind of access (e.g., read vs. write) is allowed. There are different kinds of access control policies, e.g., role-based policies vs. discretionary policies. 12 | 13 | • Address space (1) - The range of possible (physical or virtual) addresses available to a process or system. 14 | 15 | • Address Space Layout Randomization (ASLR) (2) - This is a technique by which the starting address of memory areas is chosen randomly when a process is executed. Such randomization makes it harder to perform attacks which might otherwise rely on addresses not changing. 16 | 17 | • Alias (5) - An alias is another name for the same thing. In programming, this comes up with pointers: a program may have two pointers to the same object, where one pointer is an alias for the other. 18 | 19 | • Architecture (1) - Short for "computer architecture." Refers to the hardware computing platform that runs programs, which notably consists of a central processing unit (CPU), memory, and peripherals. 20 | 21 | • Audit (4) - The process of determining whether a security breach has occurred, and how. A system must be built to be auditable, e.g., by logging security-relevant data. Can also refer to the process of studying a system for vulnerabilities. 22 | 23 | • Authentication (4) - The process by which the purported identity of an actor is confirmed. Examples include password checking and biometric scanning. 24 | 25 | • Authorization (4) - The process by which a principal's proposed action is determined to be acceptable, or not, according to a system's security policy. 26 | 27 | • Availability (0,4) - Refers to a classic security requirement about a system's operation; a system is available if it can be accessed by authorized principals when sought. A violation of availability is often called a denial of service. 28 | 29 | B 30 | 31 | • Basic block (2) - A sequence of statements in a program where control always begins at the start of the block, and flows from one statement to the next, until the last statement, which ends with a branch (to a different basic block), or halt instruction. 32 | 33 | • Big endian (project 1) - Big-endian systems store the most significant byte of a word in the smallest address and the least significant byte is stored in the largest address. 34 | 35 | • Blacklist (3) - A collection of possibly harmful elements that are checked, removed, or modified during input validation 36 | 37 | • Branch (2) - A non-sequential control transfer. Branches can be conditional --- they occur only if a condition is met --- or unconditional (sometimes referred to as "jumps"). 38 | 39 | • Buffer overflow (1) - A vulnerability in a program in which an attacker can cause a pointer to access outside of the intended bounds of the buffer it points to. Sometimes this term more narrowly refers to the act of writing beyond the bounds of a buffer, but in this course we use it more generally to include reads as well. 40 | 41 | • Bug (0) - A bug is a coding mistake in a program that causes it to behave incorrectly and/or insecurely. 42 | 43 | C 44 | 45 | • Call graph (2) - a graphical representation of the program where nodes are functions and edges indicate that source node's function could call the target node's function. 46 | 47 | • Capability (3) - a communicable, unforgeable (or hard to forge) token of authority. 48 | 49 | • Chown (4) - A system call by which one process can change the owner of a file to a different principal. 50 | 51 | • Chroot (4) - A system call by which the current process's current working directory is made to look like the root directory of the file system, making inaccessible all the directories that are not descendants of the current directory. 52 | 53 | • Client (3) - one role in a communicating pair (the other being the server), usually initiating the communication by requesting a service. 54 | 55 | • Complete mediation (4) - A requirement of a secure computer system: all security-relevant actions must mediated so they can be authorized, or there can be a breach of security. 56 | 57 | • Compiler (1) - A compiler is a program that translates a program written in one language into an equivalent program in another language. Typically, a compiler takes a program in a high-level language, like C or FORTRAN, and compiles it to a program into the language of a particular processor, which can then run that program. 58 | 59 | • Completeness (5) - A complete analysis is one that, if some property X is true, then analysis says X is true. As applied to static analysis, we interpret completeness to mean: if the analysis says that there is a bug, then there really is one; i.e., there are no false positives. 60 | 61 | • Concolic execution (5) - A kind of symbolic execution in which we run the program concretely, but keep track of symbolic values and the path condition "on the side". When the program terminates, this information can be used to generate a test that will take the program down a different path. 62 | 63 | • Confidentiality (0,4) - Refers to a classic security requirement about a system's data; data enjoys confidentiality if it cannot be learned by an unauthorized principal. Also referred to as secrecy and privacy (where the latter is used when referring to an individual) 64 | 65 | • Constraint graph (5) - An abstraction of a program that expresses directional constraints on its behavior. For example, when considering flow analysis, constraints indicate whether data can flow form one variable/position to another, and all constraints together can be visualized as a graph. 66 | 67 | • Context sensitivity (5) - A feature that adds precision to a static analysis whereby a call to a function from one part of the program can be distinguished (i.e., analyzed separately from) another call. 68 | 69 | • Control flow graph (CFG) (2) - a graphical representation of the program, where nodes in the graph are basic blocks, and edges indicate the possibility of control transferring from the source block to the target block. 70 | 71 | • Control flow integrity (CFI) (2) - This is a property of a program execution. An execution satisfies control flow integrity if it conforms to a model of the program's control flow, determined in advance. Typically this model is a control-flow graph. CFI is often enforced as an in-line reference monitor. 72 | 73 | • Cookie (3) - a piece of data associated with a particular web host and stored by the client's browser. Sent along with subsequent requests to that host. Used to implement sessions and personalization, and privacy-threatening tracking. 74 | 75 | • Cross-site Request Forgery (CSRF) (3) - An attack by which a browser is induced by one site to submit a request to another site to perform an illicit action. 76 | 77 | • Cross-site Scripting (XSS) (3) - An attack whose goal is to get a browser to execute a Javascript program originating at one site to execute with the privileges (according to the same-origin policy) of another site. 78 | 79 | D 80 | 81 | • Dangling pointer (1) - A dangling pointer is a pointer to memory that has been deallocated. Sometimes also called a stale pointer. A dangling pointer dereference is a bug that occurs when the program tries to access the memory pointed to by a dangling pointer. 82 | 83 | • Data execution prevention (DEP) (2) - DEP is a service provided by the hardware and/or operating system that enforces memory can either be writeable or executable, not both. With DEP enabled, attacker-provided buffers cannot be executed directly, and thus cannot (usefully) contain code. DEP does not prevent return-to-libc or ROP attacks, which use code already in the program. 84 | 85 | • Defect (0) - A defect is a problem in a software system. The problem could be either in the design of the system, in which case we call it a flaw, or in the implementation, in which case we call it a bug 86 | 87 | • Dereference (1) - To dereference a pointer means to either read or write the memory that the pointer points to 88 | 89 | • Direct call (2) - A call or jump to a target where the target is a constant. For example, the call printf("hello\n") directly calls the printf function. 90 | 91 | • Dynamic analysis (5,6) - An analysis of a program's execution, often designed to find bugs. Oftentimes this analysis happens concurrently with the execution, and may terminate that execution if it observes illegal behavior. 92 | 93 | E 94 | 95 | • Endiannness (project 1) - Identifies the order that bytes are stored in memory to make up a multi-byte value. Can be either little endian or big endian. 96 | 97 | • Environment variables (1) - These are variables whose (string) values are tracked by command shell. Environment variables are passed to programs that are spawned from the shell, along with the command-line arguments. 98 | 99 | • Escaping (3) - The process of transforming a string, altering characters that might be interpreted as control characters in the current context to be inert. For example, a user string containing a < would be escaped in an HTML context to instead be < 100 | 101 | • Exploit (1) - An exploit is a series of steps by which an adversary interacts with a system to turn a vulnerability, or vulnerabilities, in the system into an attack whose outcome is to his advantage. 102 | 103 | F 104 | 105 | • File Transfer Protocol (FTP) (4) - An application layer protocol for transferring files. 106 | 107 | • Flaw (0) - A flaw is a (possibly security-relevant) defect in the design of a system. 108 | 109 | • Flow analysis (5) - A kind of static analysis that determines whether values from one position in the program could reach, or flow to, another position in the program. 110 | 111 | • Flow sensitivity (5) - A feature that adds precision to a static analysis whereby the order of the statements in the program is taken into account; a flow-insensitive analysis supposes that program statements could occur in any order. 112 | 113 | • Fork (4) - The act of a process creating a new process that is a duplicate of itself; the new process is called the child, and the forking process is called the parent. A typical action of the child process is to immediately use the exec system call to convert itself to run a different program. 114 | 115 | • Format string (1) - A format string is a descriptor used by the C printf famliy of functions to describe how the provided arguments should be formatted. 116 | 117 | • Format specifier (1) - A format specifier is one element of a format string that describes how particular arguments should be interpreted, when printed. 118 | 119 | • Frame pointer (1) - It is typical on the x86 to for the compiler to dedicate the %ebp register as the frame pointer. It contains the address of the start of the area in a stack frame at which the local variables are stored. 120 | 121 | • Fuzzing (or fuzz testing) (6) - A kind of random testing whose aim to induce a system to fail, where the expectation is that some of these bugs will be security relevant 122 | 123 | G 124 | 125 | • Gadget (2) - the name of a code block used in return oriented programming. Such blocks end in return instructions, and return-oriented programs string together gadgets to provide complete functionality. 126 | 127 | • GET (3) - a kind of HTTP request, used to retrieve a resource from a remote site. 128 | 129 | H 130 | 131 | • Halting problem (5) - The halting problem is the problem of determining, for an arbitrary program and input, whether the program will finish running or continue to run forever. This problem is known to be undecidable. 132 | 133 | • Heap (1) - An area of memory in a process responsible for storing dynamically allocated data, which the size and lifetime of that data is determined by information that is not known until run time. (Not to be confused with the heap tree-based data structure.) 134 | 135 | • Hidden Form Field (3) - A field in an HTML form that is not displayed; it is often used to track hidden state. 136 | 137 | • Hyperlink (3) - An element of a hypertext document that references, or links, a remote document. 138 | 139 | • Hypertext (3) - Indicates text that contains hyperlinks, which reference other, related documents. 140 | 141 | • Hypertext Transfer Protocol (HTTP) (3) - The protocol that underlies the World Wide Web (WWW). The protocol consists of requests from clients (either GET, or POST, usually), and responses from servers. 142 | 143 | • Hypertext Markup Language (HTML) - The core language of documents served by the WWW. Browsers render these documents and permit interacting with them. 144 | 145 | I 146 | 147 | • Immutability (2) - a memory region is immutable if it cannot be changed. For example, the text segment is often immutable. 148 | 149 | • Indirect call (2) - A call or jump to a target where the target can vary at run-time. For example, calls to function pointers (in C), and virtual method calls (in C++ and Java) are indirect. 150 | 151 | • In-line reference monitor (IRM) (2) - An IRM checks that a program's behavior corresponds to a security policy, and is implemented as part of the program, i.e., is "in-lined" within it. 152 | 153 | • Instruction pointer (1) - A register that contains the address of the currently executing instruction. On the x86, the instruction pointer is stored in the %eip register. 154 | 155 | • Instruction set (1) - The set of instruction types that can be executed by a particular computer architecture. There are different styles of instruction set; two common ones are CISC (Complex Instruction Set Computer) and RISC (Reduced Instruction Set Computing). 156 | 157 | • Integrity (0,4) - Refers to a classic security requirement about a system's data; data enjoys integrity if it cannot be modified or influenced by an unauthorized principal 158 | 159 | • Internet Control Message Protocol (ICMP) (6) - A messaging protocol used for network diagnostics 160 | 161 | J 162 | 163 | • Javascript (3) - A programming language used to write scripts (small programs) embedded in web pages, which run at the browser. The harbinger of Web 2.0. 164 | 165 | K 166 | 167 | • Keylogging (6) - The process of logging keystrokes on a machine, usually carried out surreptitiously by malware, with the goal of stealing information like passwords 168 | 169 | L 170 | 171 | • Lattice (5) - A lattice is a partially ordered set such that each pair of elements in the set has a unique least upper bounds and a unique greatest lower bound. Lattices are often a foundation of static flow analysis. 172 | 173 | • Least privilege (4) - A classic security principal; this principle dictates that a subsystem should be given only the privilege it needs, and no more, to carry out its responsibilities. Limiting privilege limits damage if the subsystem is compromised. 174 | 175 | • Little Endian (project 1) - Little-endian systems store the least significant byte of a word in the smallest address, and the most significant byte in the largest address. 176 | 177 | • LLVM (2) - The LLVM Project is a collection of modular and reusable compiler and toolchain technologies. 178 | 179 | M 180 | 181 | • Memory safety (2) - A program execution is memory safe it is both spatially safe and temporally safe (these terms are elsewhere in this glossary). 182 | 183 | • Multi-factor authentication (MFA) (4) - Authentication protocols typically test multiple factors, e.g., what a purported principal knows, is, or has. Multi-factor authentication involves testing multiple factors, not just one. For example, it may ask for a password (what you know) and a text message (what you have -- a phone). 184 | 185 | N 186 | 187 | • Nop sled (1) - A nop sled is a sequence of "no-op" instructions. It is an element of an exploit that is useful when the exact address of injected shellcode is not known. The nop sled precedes the shellcode, so landing anywhere in the sled will drive the program toward the shellcode. 188 | 189 | • NUL terminator (1) - The character, a zero (or NUL) used to terminate a C string. 190 | 191 | O 192 | 193 | • Operating system (0) - A program that supports a computer's basic functions, which include starting, scheduling, and managing processes, and mediating access by those processes to input/output devices, like the stable storage (disk) and the network. 194 | 195 | P 196 | 197 | • Parse tree (3) - A representation of how a string is parsed according to a particular grammar, which identifies the structural elements of that string. 198 | 199 | • Path sensitivity (5) - A feature that adds precision to a static analysis whereby the order of the statements in the program is taken into account, as is the set of conditionals that have been followed. As such, it is strictly more precise than a flow-sensitive analysis. 200 | 201 | • Payload (6) - The data injected into a vulnerable program to perform an exploit 202 | 203 | • Penetration testing (6) - A means to assess the security of a complete system (or network of systems) by actively trying to find exploitable vulnerabilities. 204 | 205 | • Phishing (4) - An attack against a user, whereby the attacker masquerades as a trusted authority in an attempt to convince the user to reveal secret information or otherwise compromise something of value. 206 | 207 | • Physical address (1) - An address to a location in physical memory. 208 | 209 | • POST (3) - A HTTP request type, used to submit information to a remote server, e.g., when filling out a form as part of a request. 210 | 211 | • Precision (5) - In reference to static analysis, precision refers to faithfulness of the analysis's abstraction to the true semantics of a program: the more precise, the less abstract (and more faithful) is the analysis. 212 | 213 | • Principal (4) - The subject, or actor, in a security policy, which dictates what actions the subject can perform. A principal can be a person, a computer program, a role, etc. 214 | 215 | • Process (1) - A process is an instance of a program in execution. Starting, running, and handling the termination of a process is the responsibility of the operating system. 216 | 217 | • Program (1) - A program is a series of instructions for carrying out some task. 218 | 219 | • Program counter (1) - Another name for the instruction pointer 220 | 221 | Q 222 | 223 | R 224 | 225 | • Random testing (6) - A kind of testing that uses randomly generated inputs. Such tests may be fully automatic (as with fuzz testing), or may include pre-conditions on the input and assertions on the output. 226 | 227 | • Replay attack (4) - A kind of attack that involves replaying a recorded message in an attempt to effect, again, an action carried out previously. 228 | 229 | • Return address (1) - The address to which to restore the instruction pointer when the current function returns. This address is stored on the stack when using the standard x86 calling convention. 230 | 231 | • Return to libc (2) - This is a style of exploit that aims to get a program to run code already in the program by returning to it (e.g., through an overwritten return address). A typical retun-to-libc attack is to get the program to run the system() library call (e.g., to produce a remote shell controlled by the attacker). 232 | 233 | • Return oriented programming (ROP) (2) - This is a generalization of return-to-libc attacks, in that the attack may return to arbitrary positions, not just the start of functions, that can be sequenced together by return calls to induced attacker-preferred behavior. 234 | 235 | S 236 | 237 | • Same Origin Policy (SOP) (3) - A key security policy protecting resources (like cookies and web pages) originating from one web site from running Javascript code that originates from another site. 238 | 239 | • Sanitization (3) - The process of removing or replacing potentially harmful elements from untrusted input. 240 | 241 | • Satisfiability (SAT) solver (5) - A program that solves satisfiability constraints, which are simply boolean constraints C, involving variables (X), constants (true and false), conjunctions (C1 and C2), disjunctions (C1 or C2), and negations (not C). 242 | 243 | • SAT modulo theories (SMT) solver (5) - A program that solves satisfiability constraints coupled with constraints drawn from different theories, such as the theory of linear arithmetic, arrays, and uninterpreted functions. SMT solvers for the core of the automated reasoning portion of many automated analyses. 244 | 245 | • Scanner (6) - A tool that scans a network aiming to discover hosts and services they might be running. An example scanner is NMAP. 246 | 247 | • Scalability (5) - In reference to a static analysis, scalability refers to the analysis's ability to work effectively on large programs, and/or programs with sophisticated features. 248 | 249 | • SecComp (4) - A Linux system call by which a process's ability to carry out certain system calls is reduced. Implements the principle of least privilege. 250 | 251 | • Semantics (5) - The semantics of a program is its meaning; i.e., what actions it may perform or outputs it may prod\uce in response to certain inputs. 252 | 253 | • Server (3) - one role in a communicating pair (the other being the client). The server receives requests and provides service of some sort in response. 254 | 255 | • Shell (1) - The shell is the command prompt on Unix systems. In actuality it is an interpreter for a small "scripting" language whose aim is start, stop, compose, and otherwise work with processes. 256 | 257 | • Shellcode (1) - Shellcode is code that the attacker would like to inject when exploiting a vulnerability, such as a buffer overflow. 258 | 259 | • Sink (5) - In reference to flow analysis, a sink is a possible destination of a data flow. 260 | 261 | • Soundness (5) - A sound analysis is one that, if the analysis says that X is true, then X is true. As applied to static analysis, we interpret soundness to mean: if the analysis claims a program is error free, then it really is; i.e., there are no false negatives. 262 | 263 | • Source (5) - In reference to flow analysis, a sink is a possible starting point of a data flow. 264 | 265 | • Spatial safety (2) - A program execution is spatially safe if it does not use a pointer to access memory not "owned" by that pointer. Roughly speaking, a pointer owns the memory it points to if the pointer was constructed by legal means, and subsequent manipulations (e.g., pointer arithmetic) have not caused it to point outside those bounds. Memory safety implies spatial safety. See this blog post for details. 266 | 267 | • Spear phishing (4) - A kind of phishing that is targeted at a particular user or group of users, using targeted information to appear more convincing. 268 | 269 | • SQL Injection (3) - An attack which can effect the execution of SQL code where instead data was expected 270 | 271 | • Stack (1) - Short for "call stack", which is an area of memory in a process responsible for storing information pertaining to the active functions. The stack stores a series of stack frames, one per active function call. These are pushed onto the stack when a function is called, and popped when the function returns. 272 | 273 | • Stack canary (2) - this is a special value written to a stack frame that is used to detect evidence of a stack smashing attack. When a function goes to return, it checks that the stack canary is still intact; if not, an attack may have overflowed over it. 274 | 275 | • Stack frame (1) - A group of data on the stack that is associated with a particular function call. In the x86 standard calling convention, the stack frame stores the arguments passed to the function, the function's local variables, and other metadata about the call, such as the frame pointer and return address. 276 | 277 | • Stack pointer (1) - This is the address of the logical top of the stack. On the x86 architecture it is typically stored in the %esp register. 278 | 279 | • Static anaysis (5) - An algorithm that analyzes a computer program without running it in order to determine some property (or many properties) about its executions. 280 | 281 | • Static data area (1) - The area of memory in a process that stores the program's global variables. 282 | 283 | • Static single assignment (SSA) form (5) - Programs in SSA form may not assign to a variable more than once (a "static single assignment"). Programs in such form make them easier to analysis, particularly when one is interested in flow sensitivity. 284 | 285 | • Structured Query Language (SQL) (3) - A special-purpose programming language designed for managing (querying, updating, inserting, and deleting) data held in a relational database management system (RDBMS). 286 | 287 | • Symbolic execution (5) - A technique for automated program analysis in which certain variables are treated as symbolic, rather than as having concrete values. Symbolic exectuion falls somewhere between testing (in a sense you are "running" the programs) and static analysis (each run represents many concrete runs). 288 | 289 | • SYN and SYN/ACK (6) - Two particular packets in the TCP connection setup protocol 290 | 291 | T 292 | 293 | • Temporal safety (2) - A program execution is temporally safe it does not use undefined memory. Undefined memory has either never been allocated, or has been allocated but then freed. Memory safety implies temporal safety. See this blog post for details. 294 | 295 | • Text segment (1) - The area of memory in a process that stores the program code. 296 | 297 | • Transmission Control Protocol (TCP) (3) - TCP is one of the core protocols of the Internet protocol suite (IP), and provides reliable, streaming data delivery (overtop an unreliable medium). 298 | 299 | • Trusted computing base (TCB) (4) - The portion of a system that must be trusted if the system's operation is to be secure. Ideally, the trusted computing base is small and simple, so that trust placed in it is warranted. 300 | 301 | • Turing completeness (2) - A Turing complete system or language is one that can simulate a single-taped Turing machine. Such a machine is known to be very computationally expressive, so the Turing completeness of a system shows that it is similarly very expressive. 302 | 303 | • Type inference (5) - A kind of static analysis whose goal is to assign a type to a program fragment (like a variable or function). Types may be standard language types (like int or float) or enhanced types expressing other program properties (like tainted int or untainted float). 304 | 305 | • Type safety (2) - Type safety is a consistency property of a programming language: it states that programs accepted by the language's type system are also well-defined. What this means depends on the type system. See this blog post for more detail. 306 | 307 | U 308 | 309 | • Undecidability (5) - An undecidable problem is a decision problem for which it is known to be impossible to construct a single algorithm that always leads to a correct yes-or-no answer. The halting problem is an example of an undecidable problem. 310 | 311 | • Universal Resource Locator (URL) (3) - The name of a document on the WWW. Consists of three parts: the protocol by which the document can be retrieved; the host at which the document is located; and the path at that host that names the document. 312 | 313 | • User Datagram Protocol (UDP) (6) - A protocol that supports unreliable packet delivery over IP 314 | 315 | V 316 | 317 | • Virtual address (1) - An address used by a process to access memory; this address is translated by the hardware, with help from the operating system, to an actual physical memory address. Virtual memory is useful for allowing processes to always have the same address space no matter what physical memory they actual use when running. They also give the illusion that the process has more memory than it actually does. 318 | 319 | • Vulnerability (1) - A bug in a program that could potentially be exploited by an attacker to compromise security in some fashion. 320 | 321 | W 322 | 323 | • Web proxy (6) - A program that intercepts traffic sent between a web browser and web server, providing the capability to record it, modify it and/or forward it, etc. Examples include the Burp suite, and OWASP ZAP. 324 | 325 | • Web spider (6) - A program that explores the structure of a web site (or set of sites), following links from one page to the next, to create a model of the overall network of web pages. Burp Suite and OWASP ZAP both implement Spider functionality. 326 | 327 | • Whitelist (3) - A collection of known-good elements against which untrusted input is validated; non-whitelisted elements are rejected. 328 | 329 | • Worldwide Web (WWW) (3) - Refers to the collection of servers that communicate HTML documents via HTTP, over the Internet. 330 | 331 | • W xor X (2) - Stands for "Writable or executable, but not both". Another name for Data Execution Prevention (DEP). 332 | 333 | X 334 | 335 | • XSS (3) - Stands for cross-site scripting. 336 | 337 | Y 338 | 339 | Z -------------------------------------------------------------------------------- /info: -------------------------------------------------------------------------------- 1 | https://www.coursera.org/learn/software-security/ -------------------------------------------------------------------------------- /syllabus: -------------------------------------------------------------------------------- 1 | Preparation 2 | 3 | Prior to the official opening of the course, there is some brief introductory material that describes in some detail the course scope, content, and the expected background of learners. To help learners decide whether they have the right background, we have put together a qualifying quiz; failure to do well on the quiz (scoring a 70% or higher) suggests that the student may not be well-prepared to take the course without additional study. 4 | Weeks and Themes 5 | 6 | The core content of the course is as follows, with one topic per week: 7 | 8 | 1 Low-level, memory-based attacks, including stack smashing, format string attacks, stale memory access attacks, and return-oriented Programming (ROP) 9 | 10 | 2 Defenses against memory-based attacks, including stack canaries, non-executable data (aka W+X or DEP), address space layout randomization (ASLR), memory-safety enforcement (e.g., SoftBound), control-flow Integrity (CFI) 11 | 12 | 3 Web security, covering attacks like SQL injection, Cross-site scripting (XSS), Cross-site request forgery (CSRF), and Session hijacking, and defenses that have in common the idea of input validation 13 | 14 | 4 Secure design, covering ideas like threat modeling and security design principles, including organizing ideas like favor simplicity, trust with reluctance, and defend in depth; we present real-world examples of good and bad designs 15 | 16 | 5 Automated code review with static analysis and symbolic execution, presenting foundations and tradeoffs and using static taint analysis and whitebox fuzz testing as detailed examples 17 | 18 | 6 Penetration testing, presenting an overview of goals, techniques, and tools of the trade 19 | Assessment 20 | 21 | There will be an quiz each week covering the material presented that week. These quizzes will be due after two weeks at 8am ET (i.e., just prior to the release of that week's material). 22 | 23 | There will also be three hands-on projects. 24 | 25 | 1 Buffer overflow attacks: The lab walks you through how a buffer overflow occurs, and how it can be exploited. 26 | 27 | 2 Web application security: The lab asks you to find and exploit common vulnerabilities in web applications, like SQL injection and cross-site scripting 28 | 29 | 3 Static analysis for finding security bugs: The lab will give you some experience using tools that aim to find security flaws automatically 30 | 31 | Students will carry out the work of these projects at home, and to show that they have done so, will take a project-specific quiz. -------------------------------------------------------------------------------- /w1/1_intro-to-security.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w1/1_intro-to-security.pdf -------------------------------------------------------------------------------- /w1/2_software-security.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w1/2_software-security.pdf -------------------------------------------------------------------------------- /w1/3_course-overview.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w1/3_course-overview.pdf -------------------------------------------------------------------------------- /w1/4_buffer-overflow-intro.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w1/4_buffer-overflow-intro.pdf -------------------------------------------------------------------------------- /w1/5_memory-layout.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w1/5_memory-layout.pdf -------------------------------------------------------------------------------- /w1/6_overflow-attack.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w1/6_overflow-attack.pdf -------------------------------------------------------------------------------- /w1/7_code-injection.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w1/7_code-injection.pdf -------------------------------------------------------------------------------- /w1/8_other-memory-attacks.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w1/8_other-memory-attacks.pdf -------------------------------------------------------------------------------- /w1/9_format-string-attacks.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w1/9_format-string-attacks.pdf -------------------------------------------------------------------------------- /w1/project-1/info: -------------------------------------------------------------------------------- 1 | Exploiting Buffer Overflows in C 2 | 3 | This project will give you some hands-on experience to understand buffer overflows and how to exploit them. You will carry out the project using a virtual machine, on your own computer. In carrying it out, you will have to answer specific questions, given at the bottom, to show that you have followed each of the necessary steps. 4 | Installing and running the Virtual Machine 5 | 6 | This project will use a virtual machine in the VirtualBox format. The overall VirtualBox manual is available here. 7 | 8 | The first step is to install VirtualBox on your computer; our VM images have been tested with version 4.3.18. There are specific instructions for installing VirtualBox for computers running Windows, Linux, and Mac OSX. 9 | 10 | The next step is to download the virtual machine image, in OVF format, that we will use for the project. It has extension .ova meaning it is an archive with all of the relevant materials in it. The file can be found https://d396qusza40orc.cloudfront.net/softwaresec/virtual_machine/mooc-vm3.ova. The file is 1.3 GB in size. There is also a torrent file, available here. The virtual machine runs a version of Ubuntu Linux. The SHA1 of the file is 6fb69359d595d81599713c4d02dc8e947d3d6cef. 11 | 12 | Finally, you must import this OVF file, which is called mooc-vm.ova (or mooc-vm2.ova for the smaller version), and run it. To import it, it should be as simple as double-clicking the .ova file. Doing so will start VirtualBox and ask you whether to import it the image. You should then click "import". Alternatively, rather than double clicking the archive file, you can select "File" -> "Import appliance" from the Manager window and select the file. Further instructions are available here. Note that if using an earlier version of Virtual Box (4.2.x and earlier), the VM may not import; some have had success importing by disabling the DVD and USB flags. 13 | 14 | Having imported the VM, you should see it in your list of VMs. Select it and click "Start". This will open a window running the virtual machine, starting up Ubuntu Linux. When you get to a login screen, use username "seed" and password is "dees" (but without quotes). Then start up a terminal window -- there is an icon in the menu bar at the top for doing so (it looks like a computer monitor). 15 | The vulnerable program 16 | 17 | We have placed a C program wisdom-alt.c in the projects/1 directory in the virtual machine. Type cd projects/1 to change into this directory. If you type ls you will see that also in this directory is a compiled version of the program, called wisdom-alt. This executable was produced by invoking gcc -fno-stack-protector -ggdb -m32 wisdom-alt.c -o wisdom-alt (in case you accidentally delete it and need to reproduce it). 18 | Running the program 19 | 20 | The program reads data from the stdin (i.e., the keyboard) and writes to stdout (i.e., the terminal). You can run the program by typing ./wisdom-alt on the command prompt. When we do this, we see the following greeting: 21 | 22 | seed@seed-desktop:~/projects/1$ ./wisdom-alt 23 | Hello there 24 | 1. Receive wisdom 25 | 2. Add wisdom 26 | Selection > 27 | 28 | At this point, it is waiting for the user to type something in. Typing the number 1 allows you to "receive wisdom" and typing 2 allows you to "add wisdom". Extending the interaction, suppose we type 1 (and a carriage return). 29 | 30 | seed@seed-desktop:~/projects/1$ ./wisdom-alt 31 | Hello there 32 | 1. Receive wisdom 33 | 2. Add wisdom 34 | Selection >1 35 | no wisdom 36 | Hello there 37 | 1. Receive wisdom 38 | 2. Add wisdom 39 | Selection > 40 | 41 | Notice that it outputs no wisdom and then repeats the greeting. Now if we type 2 we can try to add some wisdom; here's what happens: 42 | 43 | Selection >2 44 | Enter some wisdom 45 | 46 | Now the program is waiting for the user to type something in. Suppose we type in sleep is important and press return. Then we will get the standard greeting again. If we type 1 at that point we will get the following: 47 | 48 | Selection >2 49 | Enter some wisdom 50 | sleep is important 51 | Hello there 52 | 1. Receive wisdom 53 | 2. Add wisdom 54 | Selection >1 55 | sleep is important 56 | Hello there 57 | 1. Receive wisdom 58 | 2. Add wisdom 59 | Selection > 60 | 61 | We can continue to add wisdom, by typing 2. For example, if we did this sequence again, with the entry exercise is useful, we would get: 62 | 63 | Selection >2 64 | Enter some wisdom 65 | exercise is useful 66 | Hello there 67 | 1. Receive wisdom 68 | 2. Add wisdom 69 | Selection >1 70 | sleep is important 71 | exercise is useful 72 | Hello there 73 | 1. Receive wisdom 74 | 2. Add wisdom 75 | Selection > 76 | 77 | We can keep doing this as long as we like. We can terminate interacting with the program by typing control-D. 78 | Crash! 79 | 80 | This program is vulnerable to a buffer overflow. It is easy to see there is a problem, by typing in something other than 1 or 2. For example, type in 156. 81 | 82 | seed@seed-desktop:~/projects/1$ ./wisdom-alt 83 | Hello there 84 | 1. Receive wisdom 85 | 2. Add wisdom 86 | Selection >156 87 | 88 | Segmentation fault 89 | 90 | In fact, the program has (at least) two vulnerabilities; the above is demonstrating one of them, but there is one other. Your job in this lab is to find and exploit both vulnerabilities. The lab will guide you through steps to do so, and you will answer questions in the on-line quiz to show that you took each of these steps. 91 | Exploiting the program 92 | 93 | We are now going to show you some tools you'll need to exploit this program. 94 | Entering binary data 95 | 96 | To exploit the program, you will need to enter non-printable characters, i.e., binary data. To input binary data to the program, use the following command line instead: 97 | 98 | ./runbin.sh 99 | 100 | Then we can type in binary-format strings (e.g., with hex escaping). For example: 101 | 102 | seed@seed-desktop:~/projects/1$ ./runbin.sh 103 | Hello there 104 | 1. Receive wisdom 105 | 2. Add wisdom 106 | Selection >2 107 | Enter some wisdom 108 | \x41\x41 109 | Hello there 110 | 1. Receive wisdom 111 | 2. Add wisdom 112 | Selection >1 113 | AA 114 | 115 | In the above, \x41\x41 represents two bytes, defined in hexadecial format. 41 in hex is 65 in decimal, which in ASCII is the character A. As a result, when we ask for wisdom, the program prints AA. Entering something like \x07 would be a byte 7. This is not a printable character, but is the "bell". So when it "prints," you would actually hear a sound (if sound were enabled on this VM). 116 | 117 | To exploit the program, you will have to enter sequences of binary bytes that contain addresses, which are 4-byte (i.e., 32-bit) words on the VM. The x86 architecture is "little-endian", meaning that the bytes in a word are stored from least significant to most significant. That means that the hexadecimal address 0xabcdef00 would be entered as individual bytes in reverse order, i.e., \x00\xef\xcd\xab. Here is a refresher on endianness, if you need it. 118 | 119 | Note: runbin.sh is a shell script that is just a wrapper around the following code: 120 | 121 | while read -r line; do echo -e $line; done | ./wisdom-alt 122 | 123 | This is what is converting the hex digits into binary before passing them to the wisdom-alt program. When carrying out the lab, please use the runbin.sh program, and not the above code directly, or your answers may be slightly off, as discussed at the end. 124 | Using GDB 125 | 126 | To exploit the program, you will have to learn some information about how it is laid out in memory. You can find out this information using the gdb program debugger. You can attach gdb to your running program, and then use it to print information about the state of that program, and step through executions of that program. 127 | 128 | To attach gdb to wisdom-alt, you should first invoke ./runbin.sh, and then, in a separate terminal, from the projects/1 directory invoke the following line: 129 | 130 | gdb -p `pgrep wisdom-alt` 131 | 132 | The -p option to gdb tells it to attach to a running program with the process ID (PID) given to the option. The command pgrep wisdom-alt searches the process table to find the PID of the wisdom-alt program; this PID is then fed as the argument to -p. Be warned: If you have multiple wisdom-alt programs running, you may not attach to the one you expect! Make sure they are all killed (perhaps by killing and restarting the terminals you started them in) if you run into trouble. Also, be sure you use backquotes around pgrep wisdom-alt and not forward quotes. 133 | 134 | Once you have connected to the process, you can start using gdb commands to start examining its state and controlling it. For example: 135 | 136 | seed@seed-desktop:~/projects/1$ gdb -p `pgrep wisdom-alt` 137 | 138 | GNU gdb 6.8-debian 139 | Copyright (C) 2008 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later 140 | This is free software: you are free to change and redistribute it. 141 | There is NO WARRANTY, to the extent permitted by law. Type "show copying" 142 | and "show warranty" for details. 143 | This GDB was configured as "i486-linux-gnu". 144 | Attaching to process 29727 145 | Reading symbols from /home/seed/projects/1/wisdom-alt...done. 146 | Reading symbols from /lib/tls/i686/cmov/libc.so.6...done. 147 | Loaded symbols for /lib/tls/i686/cmov/libc.so.6 148 | Reading symbols from /lib/ld-linux.so.2...done. 149 | Loaded symbols for /lib/ld-linux.so.2 150 | 0xb7fe1430 in __kernel_vsyscall () 151 | (gdb) 152 | 153 | This shows starting gdb and attaching it to a running wisdom-alt process. Then the gdb command prompt comes up. At this point, the execution of that program is paused, and we can start entering commands. For example: 154 | 155 | (gdb) break wisdom-alt.c:100 156 | Breakpoint 1 at 0x80487ea: file wisdom-alt.c, line 100. 157 | (gdb) cont 158 | Continuing. 159 | 160 | Here we enter a command to set a breakpoint at line 100 of wisdom-alt.c. Then we enter command cont (which is short for continue) to tell the program to resume its execution. In the other terminal, running wisdom-alt we enter 2 and press return. This causes execution to reach line 100, so the breakpoint fires, and the gdb command prompt comes up again, pausing the program in the process. 161 | 162 | Breakpoint 1, main () at wisdom-alt.c:100 163 | 100 int s = atoi(buf); 164 | (gdb) next 165 | 101 fptr tmp = ptrs[s]; 166 | (gdb) print s 167 | $1 = 2 168 | (gdb) print &r 169 | $2 = (int *) 0xbffff530 170 | (gdb) cont 171 | Continuing. 172 | 173 | Then, we control the program by stepping using "next", which executes the current line of code, proceeding to the next. Then we print the contents of variable s with "print", and it displays the value we entered in the other terminal. Then we continue execution by entering "cont". In the other terminal we see the prompt to enter some wisdom. 174 | 175 | When you are done working with gdb (perhaps when you've terminated the other program), just type quit to exit. 176 | 177 | The basic GDB commands you will want to use are those we have already demonstrated: setting break points, stepping through execution, and printing values. If you are not familiar with GDB already, a quick GDB reference is available here, and a more in depth GDB tutorial is available here. You would find it helpful to be familiar with the "print", "break", and "step" commands. A full GDB user's manual is also available. 178 | Questions 179 | 180 | You are now ready to start your process of developing an exploit. When you complete this section's questions, you can enter your answers in the on-line assessment. 181 | 182 | The first step is to identify where the vulnerabilities are. To do that you will have to look through the code of wisdom-alt.c. You can do this by using an editor on Linux virtual machine, like vi or emacs, both of which are installed. Alternatively you can look through the file on your own machine outside of the VM, in an editor of your choice --- the file is available here. 183 | 184 | After looking over the code to see how it works, answer the following four questions. 185 | 186 | There is a stack-based overflow in the program. What is the name of the stack-allocated variable that contains the overflowed buffer? 187 | Consider the buffer you just identified: Running what line of code will overflow the buffer? (We want the line number, not the code itself.) 188 | There is another vulnerability, not dependent at all on the first, involving a non-stack-allocated buffer that can be indexed outside its bounds (which, broadly construed, is a kind of buffer overflow). What variable contains this buffer? 189 | Consider the buffer you just identified: Running what line of code overflows the buffer? (We want the number here, not the code itself.) 190 | 191 | Now use GDB to examine the running the program and answer the following questions. These questions are basically going to walk you through constructing an exploit of the non-stack-based overflow vulnerability you just identified. We will do less "hand holding" when asking about exploiting the stack-allocated buffer. 192 | 193 | Once you have answers for all of the questions here, you can enter them on the Coursera site for full credit. 194 | 195 | Important: When carrying out the lab, you must follow the instructions given above exactly for running the program (using runbin.sh) and using GDB (attaching to wisdom-alt in a separate terminal, and not running gdb ./wisdom-alt) or else the answers you get may not match the ones we are expecting. In particular, the addresses of stack variables may be different. These addresses might also be different if you have altered any environment variables in the Ubuntu terminals. To confirm that things are as they should be, recall the GDB interaction above, where we print the address &r with the result being 0xbffff530 -- if you are not getting that result when you reproduce that interaction then something is wrong. You should restart fresh terminals and begin from scratch, following the instructions exactly. 196 | 197 | On to the first exploit: 198 | 199 | What is the address of buf (the local variable in the main function)? Enter the answer in either hexadecimal format (a 0x followed by 8 "digits" 0-9 or a-f, like 0xbfff0014) or decimal format. Note here that we want the address of buf, not its contents. 200 | What is the address of ptrs (the global variable) ? As with the previous question, use hex or decimal format. 201 | What is the address of write_secret (the function) ? Use hex or decimal. 202 | What is the address of p (the local variable in the main function) ? Use hex, or decimal format. 203 | What input do you provide to the program so that ptrs[s] reads (and then tries to execute) the contents of local variable p instead of a function pointer stored in the buffer pointed to by ptrs? You can determine the answer by performing a little arithmetic on the addresses you have already gathered above -- be careful that you take into account the size of a pointer when doing pointer arithmetic. If successful, you will end up executing the pat_on_back function. Enter your answer as an unsigned integer. 204 | What do you enter so that ptrs[s] reads (and then tries to execute) starting from the 65th byte in buf, i.e., the location at buf[64]? Enter your answer as an unsigned integer. 205 | What do you replace \xEE\xEE\xEE\xEE with in the following input to the program (which due to the overflow will be filling in the 65th-68th bytes of buf) so that the ptrs[s] operation executes the write_secret function, thus dumping the secret? (Hint: Be sure to take endianness into account.) 771675175\x00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\xEE\xEE\xEE\xEE 206 | 207 | Now let's consider the other vulnerability: 208 | 209 | Suppose you wanted to overflow the wis variable to perform a stack smashing attack. You could do this by entering 2 to call put_wisdom, and then enter enough bytes to overwrite the return address of that function, replacing it with the address of write_secret. How many bytes do you need to enter prior to the address of write_secret? 210 | 211 | To work out the answer here, you might find it useful to use the GDB backtrace command, which prints out the current stack, and the x command, which prints a "hex dump" of the bytes at a given address. For example, by typing x/48xw $esp you would print out 48 words (the w) in hexadecimal format (the x) starting at the address stored in register $esp. 212 | 213 | Now that you have answered all the questions, enter them in the on-line assessment, due in three weeks (just prior to the start of week 4). -------------------------------------------------------------------------------- /w1/project-1/wisdom-alt.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | char greeting[] = "Hello there\n1. Receive wisdom\n2. Add wisdom\nSelection >"; 10 | char prompt[] = "Enter some wisdom\n"; 11 | char pat[] = "Achievement unlocked!\n"; 12 | char secret[] = "secret key"; 13 | 14 | int infd = 0; /* stdin */ 15 | int outfd = 1; /* stdout */ 16 | 17 | #define DATA_SIZE 128 18 | 19 | typedef struct _WisdomList { 20 | struct _WisdomList *next; 21 | char data[DATA_SIZE]; 22 | } WisdomList; 23 | 24 | struct _WisdomList *head = NULL; 25 | 26 | typedef void (*fptr)(void); 27 | 28 | void write_secret(void) { 29 | write(outfd, secret, sizeof(secret)); 30 | return; 31 | } 32 | 33 | void pat_on_back(void) { 34 | write(outfd, pat, sizeof(pat)); 35 | return; 36 | } 37 | 38 | void get_wisdom(void) { 39 | char buf[] = "no wisdom\n"; 40 | if(head == NULL) { 41 | write(outfd, buf, sizeof(buf)-sizeof(char)); 42 | } else { 43 | WisdomList *l = head; 44 | while(l != NULL) { 45 | write(outfd, l->data, strlen(l->data)); 46 | write(outfd, "\n", 1); 47 | l = l->next; 48 | } 49 | } 50 | return; 51 | } 52 | 53 | void put_wisdom(void) { 54 | char wis[DATA_SIZE] = {0}; 55 | int r; 56 | 57 | r = write(outfd, prompt, sizeof(prompt)-sizeof(char)); 58 | if(r < 0) { 59 | return; 60 | } 61 | 62 | r = (int)gets(wis); 63 | if (r == 0) 64 | return; 65 | 66 | WisdomList *l = malloc(sizeof(WisdomList)); 67 | 68 | if(l != NULL) { 69 | memset(l, 0, sizeof(WisdomList)); 70 | strcpy(l->data, wis); 71 | if(head == NULL) { 72 | head = l; 73 | } else { 74 | WisdomList *v = head; 75 | while(v->next != NULL) { 76 | v = v->next; 77 | } 78 | v->next = l; 79 | } 80 | } 81 | 82 | return; 83 | } 84 | 85 | fptr ptrs[3] = { NULL, get_wisdom, put_wisdom }; 86 | 87 | int main(int argc, char *argv[]) { 88 | 89 | while(1) { 90 | char buf[1024] = {0}; 91 | int r; 92 | fptr p = pat_on_back; 93 | r = write(outfd, greeting, sizeof(greeting)-sizeof(char)); 94 | if(r < 0) { 95 | break; 96 | } 97 | r = read(infd, buf, sizeof(buf)-sizeof(char)); 98 | if(r > 0) { 99 | buf[r] = '\0'; 100 | int s = atoi(buf); 101 | fptr tmp = ptrs[s]; 102 | tmp(); 103 | } else { 104 | break; 105 | } 106 | } 107 | 108 | return 0; 109 | } 110 | -------------------------------------------------------------------------------- /w1/project-1/wisdom-alt_others_annotation.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | char greeting[] = "Hello there\n1. Receive wisdom\n2. Add wisdom\nSelection >"; 10 | char prompt[] = "Enter some wisdom\n"; 11 | char pat[] = "Achievement unlocked!\n"; 12 | char secret[] = "secret key"; 13 | 14 | int infd = 0; /* stdin */ 15 | int outfd = 1; /* stdout */ 16 | 17 | #define DATA_SIZE 128 /* define a variable "DATA_SIZE" equal to 128 bytes */ 18 | 19 | typedef struct _WisdomList { /* define a structure named WisdomList */ 20 | struct _WisdomList *next; /* declare a pointer to the next item */ 21 | char data[DATA_SIZE]; /* declare an array named "data" able to hold 128 chars */ 22 | } WisdomList; 23 | 24 | struct _WisdomList *head = NULL; /* set the first pointer to NULL */ 25 | 26 | typedef void (*fptr)(void); /* define a "pointer" variable fptr */ 27 | /* a void pointer can point to the address of any variable type */ 28 | void write_secret(void) { 29 | write(outfd, secret, sizeof(secret)); /* write secret ("secret key") of "size" sizeof(secret) to stdout */ 30 | return; 31 | } 32 | 33 | void pat_on_back(void) { 34 | write(outfd, pat, sizeof(pat)); /* write pat ("Achievement unlocked!") to stdout */ 35 | return; 36 | } 37 | 38 | void get_wisdom(void) { 39 | char buf[] = "no wisdom\n"; /* declare an array called buf and initialize it with "no wisdom\n" */ 40 | if(head == NULL) { /* if the first pointer points to NULL (no stored wisdom) */ 41 | write(outfd, buf, sizeof(buf)-sizeof(char)); /* write the contents of buf (i.e., "no wisdom") to stdout */ 42 | } else { /* if head is not NULL (i.e., some wisdom has been stored) */ 43 | WisdomList *l = head; /* store the head pointer in "l" */ 44 | while(l != NULL) { /* as long as the pointer is not NULL */ 45 | write(outfd, l->data, strlen(l->data)); /* find the data "l" is pointing to and write it to stdout */ 46 | write(outfd, "\n", 1); /* write a newline char */ 47 | l = l->next; /* find the next pointer and store it in l */ 48 | } 49 | } 50 | return; 51 | } 52 | 53 | void put_wisdom(void) { 54 | char wis[DATA_SIZE] = {0}; /* declare an array of chars named wis (128 bytes) and initialize all to 0 */ 55 | int r; /* declare an integer with name r */ 56 | 57 | r = write(outfd, prompt, sizeof(prompt)-sizeof(char)); /* write the prompt to "Enter some wisdom" to stdout */ 58 | if(r < 0) { 59 | return; 60 | } 61 | 62 | r = (int)gets(wis); /* read a string from the "wis" array, cast to an int, and store it in r */ 63 | if (r == 0) /* declare an integer named "r" */ 64 | return; 65 | 66 | WisdomList *l = malloc(sizeof(WisdomList)); /* return a pointer "l" to the memory allocated for a struct of type and size WisdomList */ 67 | 68 | if(l != NULL) { /* if the pointer "l" does not point to NULL */ 69 | memset(l, 0, sizeof(WisdomList)); /* set a number of bytes (designated by sizeof(WisdomList)) and pointed to by "l" equal to 0 */ 70 | strcpy(l->data, wis); /* copy the contents of "wis" into "data" (the item pointed to by "l") */ 71 | if(head == NULL) { /* if no wisdom was entered before (head == NULL) */ 72 | head = l; /* change "head"pointer to "l" */ 73 | } else { 74 | WisdomList *v = head; /* get a pointer named "v" and assign it the address "head" is pointing to */ 75 | while(v->next != NULL) { /* as long as the "next" pointer is not NULL */ 76 | v = v->next; /* move to the next pointer */ 77 | } /* the above serves to traverse the linked list to the end */ 78 | v->next = l; /* at the end of the linked list, assign the pointer "l" as the "next" pointer */ 79 | } 80 | } 81 | 82 | return; 83 | } 84 | 85 | fptr ptrs[3] = { NULL, get_wisdom, put_wisdom }; /* declare a pointer array and initialize it with three values (NULL and pointers to the functions) */ 86 | 87 | int main(int argc, char *argv[]) { /* start the main function */ 88 | 89 | while(1) { /* start an infinite loop */ 90 | char buf[1024] = {0}; /* declare an array called "buf" with 1024 bytes (i.e. 8 WisdomList items), initialize with all 0's */ 91 | int r; /* declare an integer named r */ 92 | fptr p = pat_on_back; /* declare a pointer "p" and initialize it with the address of return of the function "pat_on_back" */ 93 | r = write(outfd, greeting, sizeof(greeting)-sizeof(char));/* write the greeting to stdout */ 94 | if(r < 0) { /* if write() returns -1 (error) */ 95 | break; /* break */ 96 | } 97 | r = read(infd, buf, sizeof(buf)-sizeof(char)); /* read the contents of "buf" */ 98 | if(r > 0) { /* if something was read (r equals the number of bytes read) */ 99 | buf[r] = '\0'; /* set the last item of buf to a null terminator char */ 100 | int s = atoi(buf); /* convert contents of buf into an integer, store in "s" */ 101 | fptr tmp = ptrs[s]; /* use "s" (should be 1 or 2) as the index to assign a pointer to tmp */ 102 | tmp(); /* call the function pointed to by tmp */ 103 | } else { 104 | break; /* if nothing was read in, break */ 105 | } 106 | } 107 | 108 | return 0; 109 | } 110 | -------------------------------------------------------------------------------- /w1/qualifying-quiz: -------------------------------------------------------------------------------- 1 | 1. This test is meant to test your knowledge of C programming and some basic computer science-related skills you will need to do well in this class. The outcome of the test is for your use only; it will not affect whether you can register for the class, and it will not apply to your grade if you do register. As such, we recommend that you do not research the answers on the Internet, but answer the questions to your best recollection. 2 | 3 | Consider the following variable declaration for bar in the function foo 4 | 5 | void foo() { 6 | char bar[128]; 7 | ... 8 | } 9 | 10 | Which of the following are true? 11 | 12 | *Holds 128 elements 13 | bar[1] contains the first element 14 | All elements are initialized to 0 15 | 16 | 2. Consider the following code fragment: sizeof(int*) == sizeof(int). Which one of the following is true about it? 17 | 18 | This fragment will not compile (-) 19 | This fragment always evaluates to 0 (assuming it doesn't crash) (-) 20 | This fragment always evaluates to 1 (assuming it doesn't crash) (-) 21 | This fragment's result depends on the compiler and architecture (+) 22 | This fragment will always crash 23 | 24 | 3. Suppose you are compiling for a 32-bit platform and sizeof(int) == 4. Which one of the following is equivalent to c[b] if c is of type int* and b is of type int? 25 | 26 | none of the above 27 | -1 * b[c] (-) 28 | *c+b (-) 29 | c[b][0] (-) 30 | *(c+b) (+) 31 | 32 | 4. Consider the following program. 33 | 34 | #include 35 | 36 | int foo(void) { 37 | char bar[128]; 38 | char *baz = &bar[0]; 39 | baz[127] = 0; 40 | return strlen(baz); 41 | } 42 | 43 | What are possible outcomes from running this function? Check all that apply (note that the outcomes shown are not exhaustive): 44 | 45 | returns -1 (-) 46 | returns 127 (+) 47 | returns 128 (-) 48 | returns 0 (+) 49 | crash (-) 50 | 51 | 5. Consider the following code fragment. 52 | 53 | char blah[] = "fizzbuzz"; 54 | printf("%s\n", blah+4); 55 | 56 | What happens if we try to compile and run this code? 57 | 58 | The program outputs "buzz" (+) 59 | The program outputs a blank line depending on the size of pointers (-) 60 | The program is illegal C and may not compile (-) 61 | The program outputs "fizz" (-) 62 | 63 | 6. Which of the following are true of memory returned via the malloc function? Check all that apply. 64 | 65 | It must be manually released by the programmer (+) 66 | The memory is zero-initialized (-) 67 | It is write-only (-) 68 | It is automatically released by the operating system when the pointer to which the memory is assigned goes out of scope (-) 69 | 70 | 7. Consider the following code 71 | 72 | #include 73 | #include 74 | 75 | int main(int argc, char *argv[]) { 76 | unsigned int i; 77 | unsigned int k = atoi(argv[1]); 78 | char *buf = malloc(k); /* 1 */ 79 | if(buf == 0) { 80 | return -1; 81 | } 82 | 83 | for(i = 0; i < k; i++) { 84 | buf[i] = argv[2][i]; /* 2 */ 85 | } 86 | 87 | printf("%s\n", buf); /* 3 */ 88 | 89 | return -1; 90 | } 91 | 92 | This program could crash at position 3 93 | This program could crash at 2 and 3 (+) 94 | This program could crash at 1 and 2 (-) 95 | This program could crash at position 2 (-) 96 | This program could crash at position 1 (-) 97 | This program could crash at all 3 positions (-) 98 | 99 | 8. Which of the following are true statements about the program stack? 100 | 101 | It is used to store global variables while executing a function (-) 102 | It is used as the source of memory returned by malloc() (-) 103 | It is used to store local variables while executing a function (+) 104 | The stack is managed by code emitted by the compiler (+) 105 | Management of the stack is handled automatically by the architecture (-) 106 | 107 | 9. Which of the following are true of the X86 call instruction? 108 | 109 | Branches to a specified address (+) 110 | Its target address may be specified in a general-purpose register (+) 111 | Pushes the instruction pointer value onto the stack (+) 112 | Pushes flag registers onto the stack (-) 113 | 114 | 10. Consider the following program 115 | 116 | #include 117 | #include 118 | #include 119 | 120 | int main(int argc, char *argv[]) { 121 | int **blah2 = malloc(sizeof(int*)*N); 122 | int *special = NULL; 123 | int i, j; 124 | 125 | for(i = 0; i < N; i++) { 126 | int *tmp = (int *)malloc(sizeof(int)*M); 127 | memset((void *)tmp, 0, sizeof(int)*M); 128 | if(i > N) { 129 | special = &tmp[3]; 130 | } 131 | blah2[i] = tmp; 132 | } 133 | 134 | if(special != NULL) { 135 | *special = 7; 136 | } 137 | 138 | for(i = 0; i < N; i++) { 139 | for(j = 0; j < M; j++) { 140 | printf("%d ", blah2[i][j]); 141 | } 142 | printf("\n"); 143 | } 144 | 145 | return 0; 146 | } 147 | 148 | Assuming we #define N and M to be positive integers, and the calls to malloc() succeed (the arguments do not overflow, and do not return NULL), then which of the following is true? 149 | 150 | This program crashes (-) 151 | This program outputs a matrix with at least one element being 7 (-) 152 | This program outputs a random NxM matrix (-) 153 | This program outputs a zero NxM matrix (+) 154 | This is not a valid C program (-) 155 | 156 | 11. What is TCP? 157 | 158 | It is connectionless (-) 159 | It ensures data confidentiality (-) 160 | It is a protocol that supports reliable data transfer on the Internet (+) 161 | It is a protocol often implemented on top of HTTP (-) 162 | 163 | 12. What is PHP? Pick one. 164 | 165 | The acronym for a coding standard (-) 166 | A programming language often used to implement network switches (-) 167 | A network protocol (-) 168 | A programming language often used to implement web sites (+) 169 | 170 | 13. Which of the following statements about HTML are true? 171 | 172 | Web browsers render HTML content served by web sites (+) 173 | HTML is a kind of URL (-) 174 | HTML documents have tags that identify different sorts of data (+) 175 | HTML is a text-based format (as opposed to a binary format) (+) 176 | 177 | 14. What is gcc? 178 | 179 | All of the above (-) 180 | An interpreter (-) 181 | A virtual machine (-) 182 | A compiler (+) 183 | 184 | 15. The shell command cd; ls *.xml 185 | 186 | Will list all files ending in the xml suffix in the previous working directory (-) 187 | Will list the file *.xml in the current directory (-) 188 | Will list all files ending in the xml suffix in user's home directory (+) 189 | Will list all of the files listed in the given XML file (-) 190 | -------------------------------------------------------------------------------- /w1/vm-bof-quiz: -------------------------------------------------------------------------------- 1 | 1. There is a stack-based overflow in the program. 2 | What is the name of the stack-allocated variable that contains 3 | the overflowed buffer? 4 | 5 | ans: wis 6 | 7 | 2. Consider the buffer you just identified: 8 | Running what line of code will overflow the buffer? 9 | 10 | ans: 62 11 | 12 | 3. There is another vulnerability, not dependent at all on the first, 13 | involving a non-stack allocated buffer that can be indexed outside 14 | its bounds. What variable contains this buffer? 15 | 16 | ans: ptrs 17 | 18 | 4. Consider the buffer you just identified: Running what line of code overflows the buffer? 19 | 20 | ans: 101 21 | 22 | 5. What is the address of buf? 23 | 24 | ans: 0xbfff f130 25 | 26 | 6. What is the address of ptrs? 27 | ans: 0x0804 a0d4 28 | 29 | 7, What is the address of write_secret? 30 | ans: 0x0804 8534 31 | 32 | 8. what is the address of p local to main? 33 | ans: 0xbfff f534 34 | 35 | 9. What input do you provide so that ptrs[s] reads/executes 36 | the contents of variable p instead of function in ptrs buffer? 37 | If ok, you will execute pat_on_back function. Enter your answer 38 | as an unsigned integer. 39 | 40 | ans: 41 | (p-ptrs)/4 is 42 | print /x (0xbffff534 - 0x804a0d4)/4 43 | 0x2dfed518 or 771675416 44 | 45 | 10. What do you enter so that ptrs[s] reads (and then tries to execute) 46 | starting from the 65th byte in buf, ie. the location at buf[64]? 47 | Enter your answer as an unsiged integer. 48 | 49 | ans: 50 | (gdb) print /x &buf[64] 51 | $6 = 0xbffff170 52 | (gdb) print /d (int*)&buf[64]-(int *)&ptrs 53 | $14 = 771675175 54 | 771675175 55 | 56 | 57 | 11. What do you replace \xEE\xEE\xEE\xEE with to call write_secret? 58 | 59 | ans: 60 | 61 | (gdb) print &write_secret 62 | $7 = (void (*)(void)) 0x8048534 63 | 64 | 771675175\x00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x34\x85\x04\x08 65 | 66 | 12. Suppose you wanted to overflow the wis variable to perform a stack smashing attack. You could do this by entering 2 to call put_wisdom, and then enter enough bytes to overwrite the return address of that function, replacing it with the address of write_secret. How many bytes do you need to enter prior to the address of write_secret? -------------------------------------------------------------------------------- /w1/week-1-quiz: -------------------------------------------------------------------------------- 1 | Week 1 quiz 2 | 3 | 1. Three of the following are classic security properties; which one is not? 4 | 5 | Availability 6 | Confidentiality 7 | Correctness (+) 8 | Integrity 9 | 10 | 2. What was the first buffer overflow attack? 11 | 12 | Love Bug 13 | SQL Slammer 14 | Morris Worm (+) 15 | Code Red 16 | 17 | 3. The stack is memory for storing 18 | 19 | Local variables (+) 20 | Program code 21 | Dynamically linked libraries 22 | Global variables 23 | 24 | 4. Why is it that the compiler does not know the absolute address of a local variable? 25 | 26 | Programs are not allowed to reference memory using absolute addresses 27 | The size of the address depends on the architecture the program will run on 28 | As a stack-allocated variable, it could have different addresses depending on when its containing function is called (+) 29 | Compiler writers are not very good at that sort of thing 30 | 31 | 5. When does a buffer overflow occur, generally speaking? 32 | 33 | when writing to a pointer that has been freed 34 | when copying a buffer from the stack to the heap 35 | when a pointer is used to access memory not allocated to it (+) 36 | when the program notices a buffer has filled up, and so starts to reject requests 37 | 38 | 6. How does a buffer overflow on the stack facilitate running attacker-injected code? 39 | 40 | By overwriting the return address to point to the location of that code (+) 41 | By writing directly to the instruction pointer register the address of the code 42 | By writing directly to %eax the address of the code 43 | By changing the name of the running executable, stored on the stack 44 | 45 | 7. What is a nop sled? 46 | 47 | It is an anonymous version of a mop sled 48 | It is a sequence of nops preceding injected shellcode, useful when the return address is unknown (+) 49 | It is a method of removing zero bytes from shellcode 50 | It is another name for a branch instruction at the end of sequence of nops 51 | 52 | 8. The following program is vulnerable to a buffer overflow (assuming the absence of automated defenses like ASLR, DEP, etc., which we introduce in the next unit). What is the name of the buffer that can be overflowed? 53 | 54 | #include 55 | #include 56 | 57 | #define S 100 58 | #define N 1000 59 | 60 | int main(int argc, char *argv[]) { 61 | char out[S]; 62 | char buf[N]; 63 | char msg[] = "Welcome to the argument echoing program\n"; 64 | int len = 0; 65 | buf[0] = '\0'; 66 | printf(msg); 67 | while (argc) { 68 | sprintf(out, "argument %d is %s\n", argc-1, argv[argc-1]); 69 | argc--; 70 | strncat(buf,out,sizeof(buf)-len-1); 71 | len = strlen(buf); 72 | } 73 | printf("%s",buf); 74 | return 0; 75 | } 76 | 77 | out (+) 78 | len 79 | buf 80 | msg 81 | 82 | 9. Here is the same program as the previous question. What line of code can overflow the vulnerable buffer? 83 | 84 | #include 85 | #include 86 | 87 | #define S 100 88 | #define N 1000 89 | 90 | int main(int argc, char *argv[]) { 91 | char out[S]; 92 | char buf[N]; 93 | char msg[] = "Welcome to the argument echoing program\n"; 94 | int len = 0; 95 | buf[0] = '\0'; 96 | printf(msg); 97 | while (argc) { 98 | sprintf(out, "argument %d is %s\n", argc-1, argv[argc-1]); 99 | argc--; 100 | strncat(buf,out,sizeof(buf)-len-1); 101 | len = strlen(buf); 102 | } 103 | printf("%s",buf); 104 | return 0; 105 | } 106 | 107 | sprintf(out, "argument %d is %s\n", argc-1, argv[argc-1]); (+) 108 | printf(msg) 109 | len = strlen(buf); 110 | strncat(buf,out,sizeof(buf)-len-1); 111 | printf("%s",buf); 112 | 113 | 10. Recall the vulnerable overflow from the previous two questions. We can change one line of code and make the buffer overrun go away. Which of the following one-line changes, on its own, will eliminate the vulnerability? 114 | 115 | #include 116 | #include 117 | 118 | #define S 100 119 | #define N 1000 120 | 121 | int main(int argc,char *argv[]) { 122 | char out[S]; 123 | char buf[N]; 124 | char msg[] = "Welcome to the argument echoing program\n"; 125 | int len = 0; 126 | buf[0] = '\0'; 127 | printf(msg); 128 | while (argc) { 129 | sprintf(out,"argument %d is %s\n",argc-1,argv[argc-1]); 130 | argc--; 131 | strncat(buf,out,sizeof(buf)-len-1); 132 | len = strlen(buf); 133 | } 134 | printf("%s",buf); 135 | return 0; 136 | } 137 | 138 | change printf("%s",buf) to printf(buf); 139 | change printf(msg) to printf("%s",msg); 140 | change char msg[] = "Welcome to the argument echoing program\n" to char msg[42] = "Welcome to the argument echoing program\n" 141 | change sprintf(out, "argument %d is %s\n", argc-1, argv[argc-1]) (+) 142 | to snprintf(out, S, "argument %d is %s\n", argc-1, argv[argc-1]) 143 | 144 | 11. Recall the vulnerable program from the previous few questions. Which of the following attacks do you think the program is susceptible to? 145 | 146 | #include 147 | #include 148 | 149 | #define S 100 150 | #define N 1000 151 | 152 | int main(int argc, char *argv[]) { 153 | char out[S]; 154 | char buf[N]; 155 | char msg[] = "Welcome to the argument echoing program\n"; 156 | int len = 0; 157 | buf[0] = '\0'; 158 | printf(msg); 159 | while (argc) { 160 | sprintf(out, "argument %d is %s\n", argc-1, argv[argc-1]); 161 | argc--; 162 | strncat(buf,out,sizeof(buf)-len-1); 163 | len = strlen(buf); 164 | } 165 | printf("%s",buf); 166 | return 0; 167 | } 168 | 169 | code injection 170 | data corruption 171 | reading arbitrary addresses in memory 172 | all of the above (+) 173 | 174 | 12. Recall the program again. 175 | 176 | #include 177 | #include 178 | 179 | #define S 100 180 | #define N 1000 181 | 182 | int main(int argc, char *argv[]) { 183 | char out[S]; 184 | char buf[N]; 185 | char msg[] = "Welcome to the argument echoing program\n"; 186 | int len = 0; 187 | buf[0] = '\0'; 188 | printf(msg); 189 | while (argc) { 190 | sprintf(out, "argument %d is %s\n", argc-1, argv[argc-1]); 191 | argc--; 192 | strncat(buf,out,sizeof(buf)-len-1); 193 | len = strlen(buf); 194 | } 195 | printf("%s",buf); 196 | return 0; 197 | } 198 | 199 | If we changed printf("%s",buf) to printf(buf) then the program would be vulnerable to what sort of attack? 200 | heap overflow 201 | format string attack (+) 202 | use-after-free attack 203 | all of the above 204 | 205 | 13. Exploitation of the Heartbleed bug permits 206 | 207 | overwriting cryptographic keys in memory 208 | a kind of code injection 209 | a read outside bounds of a buffer (+) 210 | a format string attack 211 | 212 | 14. Why is it that anti-virus scanners would not have found an exploitation of Heartbleed? 213 | 214 | It's a vacuous question: Heartbleed only reads outside a buffer, so 215 | there is no possible exploit 216 | Anti-virus scanners tend to look for viruses and other malicious 217 | code, but Heartbleed exploits steal secrets without injecting any code (+) 218 | Heartbleed exploits are easily mutated so the files they leave 219 | behind do not appear unusual 220 | Heartbleed attacks the anti-virus scanner itself 221 | 222 | 15. An integer overflow occurs when 223 | 224 | an integer expression's result "wraps around"; instead of creating a very large number, a very small (or negative) number ends up getting created (+) 225 | an integer is used as if it was a pointer 226 | an integer is used to access a buffer outside of the buffer's bounds 227 | there is no more space to hold integers in the program 228 | -------------------------------------------------------------------------------- /w2/1_memdefense-intro.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w2/1_memdefense-intro.pdf -------------------------------------------------------------------------------- /w2/2_memory-safety.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w2/2_memory-safety.pdf -------------------------------------------------------------------------------- /w2/3_type-safety.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w2/3_type-safety.pdf -------------------------------------------------------------------------------- /w2/4_avoiding-exploitation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w2/4_avoiding-exploitation.pdf -------------------------------------------------------------------------------- /w2/5_ROP.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w2/5_ROP.pdf -------------------------------------------------------------------------------- /w2/6_CFI.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w2/6_CFI.pdf -------------------------------------------------------------------------------- /w2/7_secure-coding.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w2/7_secure-coding.pdf -------------------------------------------------------------------------------- /w2/week-2-quiz: -------------------------------------------------------------------------------- 1 | Week 2 quiz 2 | 3 | 4 | 1. A program indexes a buffer after a pointer to that buffer has been used as a parameter to the free() function. This is 5 | 6 | A violation of temporal memory safety 7 | Correct behavior 8 | A violation of spatial memory safety 9 | An information flow violation 10 | 11 | 2. When could an integer overflow impact memory safety? 12 | 13 | If the integer was passed as a parameter to open() 14 | If the integer is passed as an argument to malloc() 15 | If the integer was passed as a parameter to printf() 16 | If the integer was used to perform pointer arithmetic 17 | If the integer is used as the denominator in a division expression 18 | 19 | 3. Which of the following are true about a language that uses garbage collection or some other automatic means (e.g., reference counting) for memory management? (Select all that apply.) 20 | 21 | The language will not have spatial memory safety violations 22 | The use of automatic memory management will provide a safety benefit, but typically at the cost of some performance 23 | The language will not have type safety violations 24 | 25 | 4. Consider the following code: 26 | 27 | char *foo(char *buf) { 28 | char *x = buf+strlen(buf); 29 | char *y = buf; 30 | while (y != x) { 31 | if (*y == 'a')break; 32 | y++; 33 | } 34 | return y; 35 | } 36 | 37 | void bar() { 38 | char input[10] = "leonard"; 39 | foo(input); 40 | } 41 | 42 | The definition of spatial safety models pointers as capabilities, which are triples (p,b,e) where p is the pointer, b is the base of the memory region the pointer is allowed to access, and e is the extent of that region. Assuming characters are 1 byte in size, what is a triple (p,b,e) for the variable y when it is returned at the end of the code? 43 | 44 | (y,&input,buf) 45 | (&input+4,&input,&input+7) 46 | (&input+4,&input,&input+10) 47 | (&input+4,0,sizeof(input)) 48 | 49 | 5. Which of the following are true about a type-safe language? (Select all that apply.) 50 | 51 | The language is object-oriented. 52 | The language is always much slower than a non-type safe language 53 | The language is also memory safe 54 | The language is sometimes memory safe, but not always 55 | 56 | 6. An engineer proposes that in addition to making the stack non-executable, your system should also make the heap non-executable. Doing so would 57 | 58 | Make the program more secure by disallowing another location for an attacker to place executable code 59 | Not make the program more secure, because attacker-controlled data cannot be stored in the heap 60 | Ensure that only the correct amount of data was written to a heap-allocated block, preventing heap overflows 61 | Ensure that memory is always deallocated 62 | 63 | 7. What is the best choice of value for a stack canary, of the following options? 64 | 65 | The constant 0 66 | The constant 7 67 | A predictable value 68 | A random value 69 | 70 | 8. A return-to-libc attack does not require that the attacker inject executable code into the vulnerable program. Which of the following is the most important reason that return-to-libc attacks are useful to the attacker? 71 | 72 | There is no need to be able to execute (writable) data 73 | The injected code might have bugs 74 | The code in libc is better than code the attacker would write 75 | There is no need to modify the application's executable code 76 | 77 | 9. In a return-oriented program (ROP), what is the role of the stack pointer? 78 | 79 | It's like the frame pointer in a normal program 80 | It's really no different than in a normal program 81 | It's like the allocation pointer used by malloc() 82 | It's like the program counter in a normal program 83 | 84 | 10. When enforcing Control Flow Integrity (CFI), there is no need to check that direct calls adhere to the control flow graph because: 85 | 86 | CFI should be deployed on systems that ensure the data is non-executable 87 | Programs that use CFI don't have direct calls 88 | The attacker is not interested in corrupting direct calls 89 | CFI should be deployed on systems that ensure the code is immutable 90 | 91 | 11. Recall that classic enforcement of CFI requires adding labels prior to branch targets, and adding code prior to the branch that checks the label to see if it's the one that is expected. Now consider the following program: 92 | 93 | int cmp1(char *a, char *b) { 94 | return strcmp(a,b); 95 | } 96 | 97 | int cmp2(char *a, char *b) { 98 | return strcmp(b,a); 99 | } 100 | 101 | typedef int (*cmpp)(char*,char*); 102 | 103 | int bar(char *buf) { 104 | cmpp p; 105 | char tmpbuff[512] = { 0 }; 106 | int l; 107 | 108 | if(buf[0] == 'a') { 109 | p = cmp1; 110 | } else { 111 | p = cmp2; 112 | } 113 | 114 | printf("%p\n", p); 115 | strcpy(tmpbuff, buf); 116 | 117 | for(l = 0; l < sizeof(tmpbuff); l++) { 118 | if(tmpbuff[l] == 0) { 119 | break; 120 | } else { 121 | if(tmpbuff[l] > 97) { 122 | tmpbuff[l] -= 32; 123 | } 124 | } 125 | } 126 | 127 | return p(tmpbuff,buf); 128 | } 129 | 130 | To ensure that the instrumented program runs correctly when not being attacked, which of the following functions would have to be given the same label? Choose at least two, but no more functions than necessary. 131 | 132 | strcpy 133 | cmp1 134 | cmp2 135 | cmpp 136 | strcmp 137 | 138 | 12. In your review of a program, you discover the following function: 139 | 140 | void aFunction(char *buf) { 141 | static char BANNED_CHARACTERS[] = { '>', '<', '!', '*' }; 142 | int l = strlen(buf); 143 | int i; 144 | 145 | for(i = 0; i < l; i++) { 146 | int j; 147 | int k = sizeof(BANNED_CHARACTERS) / sizeof(char); 148 | for(j = 0; j < k; j++) { 149 | if(buf[i] == BANNED_CHARACTERS[j]) 150 | buf[i] = ' '; 151 | } 152 | } 153 | } 154 | 155 | How would you best describe what this function is doing? 156 | Input validation by whitelisting 157 | Input sanitization by blacklisting 158 | Spatial safety enforcement 159 | Using a safe string library 160 | 161 | 13. A safe string library typically attempts to ensure which of the following? 162 | 163 | That there is sufficient space in a source and/or target string to perform operations like concatenation, copying, etc. 164 | That the strings have been properly sanitized 165 | That wide (i.e., multibyte) character strings can be used where single-byte character strings are expected. 166 | That strings from the safe library can be freely passed to the standard string library functions, and vice versa 167 | 168 | 14. A project manager proposes a C coding standard where pointer variables must be assigned to NULL after being passed to free(). Doing so: 169 | 170 | Helps code readability, but not security 171 | Is a poor security decision, because NULL pointer dereferences could cause the program to crash 172 | Stops writes to stale pointer values that might otherwise succeed and result in program compromise 173 | Prevents memory leaks, thus avoiding potential denial of service 174 | 175 | 15. A colleague proposes using a heap allocator that randomizes the addresses of allocated objects. This: 176 | 177 | Will increase performance by keeping the cache sparsely populated 178 | Will make the program more secure, because attackers frequently rely on predicting the locations of heap-allocated objects in exploits 179 | Will make the program less secure, because the application will not be able to predict the locations of heap-allocated objects 180 | Will have no impact on security or performance 181 | 182 | -------------------------------------------------------------------------------- /w3/1_web-intro.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w3/1_web-intro.pdf -------------------------------------------------------------------------------- /w3/2_web-basics.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w3/2_web-basics.pdf -------------------------------------------------------------------------------- /w3/3_sql-injection.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w3/3_sql-injection.pdf -------------------------------------------------------------------------------- /w3/4_sql-injection-countermeasures.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w3/4_sql-injection-countermeasures.pdf -------------------------------------------------------------------------------- /w3/5_web-state.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w3/5_web-state.pdf -------------------------------------------------------------------------------- /w3/6_session-hijacking.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w3/6_session-hijacking.pdf -------------------------------------------------------------------------------- /w3/7_CSRF.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w3/7_CSRF.pdf -------------------------------------------------------------------------------- /w3/8_web2.0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w3/8_web2.0.pdf -------------------------------------------------------------------------------- /w3/9_XSS.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w3/9_XSS.pdf -------------------------------------------------------------------------------- /w3/badstore-quiz: -------------------------------------------------------------------------------- 1 | 1. One of the BadStore pages has a hidden form field that establishes a new user's privilege level. What is the name of this field? 2 | 3 | ans: role 4 | 5 | 2. How many items for purchase are in BadStore's database? Use SQL injection on the quick search form field to find out. 6 | 7 | ans: 16 (*'--') 8 | 9 | 3. Which of the following operations are suppliers permitted to do? Use SQL injection to bypass authentication, or find a way to create an account as a supplier. 10 | 11 | View existing price list 12 | Cancel contract 13 | Upload price list 14 | Submit monthly bill payment 15 | Download an activity report 16 | 17 | ans: 'OR 1=1 OR' 18 | 19 | 4. Log in as joe@supplier.com --- this is possible in a variety of ways, including SQL injection. Then look at his previous orders and answer the question: What credit card number did he use to make a purchase of $46.95? Multiple answers are possible, but we will accept all of them. 20 | 21 | ans: 5500000000000004 22 | 23 | 4. Get administrator privileges and then use the admin action to look at the user database. There are two users whose emails have the form XXX@whole.biz; what is the XXX portion of either of the two users? For example, if one of the users is jackie@whole.biz, the right answer is jackie. (The answer is case-sensitive.) 24 | 25 | ans: fred 26 | 27 | 5. BadStore uses cookies to implement a session key, once you've authenticated, and for tracking the contents of the cart, once you've added something to it. You can figure out the cookies in use by BadStore in various ways. One way is to do an XSS attack on the guest book. Get the guest book to run the code and it will tell you the current cookies. (Be sure you have popups enabled on your browser or this won't work.) Alternatively, you can examine the cookies directly using Firefox developer tools. Recall that cookies are pairs key=value. What is the key of the session cookie? 28 | 29 | ans: SSOid=YWRtaW46NWViZTIyOTRlY2QwZTBmMDhlYWI3NjkwZDJhNmVlNjk6TWFzdGVyIFN5c3RlbSBBZG1p%0AbmlzdHJhdG9yOkE%3D%0A; CartID=1416121184%3A2%3A4010.5%3A1000%3A1004 30 | SSOid 31 | 32 | 6. What is the key of the cookie used for the cart? 33 | 34 | ans: CartID 35 | 36 | 7. BadStore's session cookie format is poorly designed because it is uses a predictable structure. In particular, it is an encoded string (with a URL-encoded newline at the end) of the form XXX:YYY:ZZZ:U. What are the XXX, YYY, and ZZZ portions of this string? 37 | 38 | ans: 39 | 40 | 8. BadStore's cart cookie is also an encoded string with a predictable structure XXX:YYY:... etc., and it probably contains information it shouldn't. Which field of the decoded string could an attacker change to give himself a discount on an item's price? 41 | 42 | ans: 3 43 | -------------------------------------------------------------------------------- /w3/project-2/BadStore_net_v2_1_Manual.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w3/project-2/BadStore_net_v2_1_Manual.pdf -------------------------------------------------------------------------------- /w3/project-2/info: -------------------------------------------------------------------------------- 1 | BadStore Project 2 | 3 | For this project, we will be using the BadStore.net VM, developed by Kurt Roemer and used with permission (thanks, Kurt!). It contains a vulnerable web application. Your job will be to exploit vulnerabilities we have talked about in the lectures, and answer some questions in the on-line assessment to show what you find. 4 | 5 | You can use any web browser to interact with BadStore.net, but we recommend (and will support) using Firefox (which is freely available). The reason is that Firefox has a nice set of developer tools that allow you to inspect, and modify, the contents of web pages, which will be useful when crafting attacks. If you choose to use another browser, then you will have to figure out how/whether it will permit the same interactions. 6 | Set up and start BadStore with Virtual Box 7 | 8 | The first step is to set up BadStore on your machine and get it running. 9 | 10 | BadStore is a Linux-based server application. It is distributed as a bootable ISO, which you can download from https://d396qusza40orc.cloudfront.net/softwaresec/virtual_machine/BadStore_212.iso . You may also want to download the BadStore manual https://d28rh4a8wq0iu5.cloudfront.net/softwaresec/virtual_machine/BadStore_net_v2_1_Manual.pdf, which describes the design and setup of BadStore in detail. 11 | 12 | The BadStore ISO can be booted directly, or run using a Virtual Machine Manager, like VMWare or Virtual Box. We will explain how to set it up using Virtual Box. 13 | 14 | The first step is to install Virtual Box; this project has been tested with the most recent version, 4.3.18. There are specific instructions for installing VirtualBox for computers running Windows, Linux, and Mac OSX. 15 | 16 | Now we need to create and configure a Virtual Machine to run BadStore. Do this using the following steps. 17 | 1. Create a new VirtualBox VM. 18 | 19 | Detailed instructions for doing this are here. In short: when you start Virtual Box, click the "New" icon to create a new VM. Give your VM the name BadStore; specify the operating system type as Linux; and choose 32-bit Ubuntu. You can allocate 512 MB (or more) RAM to your VM, and specify that it should create the hard-drive now. You will be asked how the image should be stored; make it a VDI with 8 GB (the default), and this part is important: make sure the "Dynamically allocated" radio button is set, so that Virtual Box will not reserve the 8 GB on your hard drive, but will allocate it on the fly. In fact, we will use none of this space, so there's no sense in reserving it in advance. 20 | 2. Assign the BadStore ISO to the CD-ROM drive of the VM. 21 | 22 | Detailed instructions are here. In short, you should select the Settings for the VM you just created, and then select the Storage tab. On the left you will see the VM's "Storage Tree" and you should see Controller: IDE as one listed. With this selected, add a new controller to this tree by clicking the little icon at the bottom with the plus on it in the lower left. It will ask you to choose whether to add CD/DVD or a Hard Disk; select CD/DVD. Then it will ask you whether to "Choose Disk" or "Leave Empty"; select "Choose Disk". A file dialog will come up and you should choose the BadStore_212.iso file that you previously downloaded. Once you do, you should see this image added below the IDE controller in the Storage Tree, and it should be the IDE Primary Master. You might also see an entry for "Empty" which was there at the start; if so, then remove it by selecting the Empty entry and clicking the icon with the minus sign on it. 23 | 3. Create a HostOnly virtual network. 24 | 25 | You will need to configure a HostOnly networking for your VM. You need to do this in two steps. The first is to create the HostOnly network. The next step is to associate that network with your VM. 26 | 27 | Details for creating a host-only network are in the VirtualBox manual. First, you must go to the network settings. For Linux or Windows, this will be under "File" -> "Preferences" -> "Network". For Mac OS, the settings are under "VirtualBox" -> "Preferences". Select the Network tab. You will be shown a list of possible networks, including NAT networks, and Host-only Networks. Select Host-only networks, and then click the icon on the right to add one. It will add an entry with a name like vboxnet0. 28 | 29 | If you cannot create a host-only network, it may be because the virtualbox kernel drivers are not properly loaded; cf. this blog post. On MacOS, this problem can be fixed by doing 30 | 31 | Select the newly created network entry and edit it by clicking the appropriate icon to the right. There are two panes, one for Adapter, the other for DHCP Server. The Adapter pane will give the IP address for the network, etc. I should be something like 192.168.56.1 with a Subnet mask of 255.255.255.0. The DHCP Server pane will show the DHCP server information. If it is not enabled with the information filled in, then enable it and fill it in as follows: 32 | 33 | Notice that the server address is the same as the adapter address, but with 2, rather than 1. Do the same on your own machine. Likewise select the address range as 110 to 200, but using the same first three octets of the adapter address. 34 | 4. Assign the BadStore VM to the HostOnly network. 35 | 36 | Now that you have created the HostOnly network, go back to the settings window for the BadStore VM and select the Network pane. Select "Host-only adapter" from the "Attached to" drop down. Select "vboxnet0" (or whatever it was from step 3) for Name. 37 | 5. Boot the BadStore VM. 38 | 39 | Now you are ready to boot your VM. Start the VM by clicking the green arrow for Start on the VirtualBox console. You will see a text window show up and a bunch of text fly by, while it's booting. (Note that, during this time, VirtualBox may "capture" your mouse pointer and keyboard and you will have to press the host key to get them back.) Eventually, the messages should get to a point where you see 40 | 41 | At this point, it will hang for a while, for some reason related to DHCP, but we aren't sure what. Within a couple of minutes (we see 2.5 minutes, consistently) the VM should finally be able to get an address. After a flurry of additional messages you should see 42 | 43 | Press enter and you'll get a prompt. 44 | 45 | If the VM does nothing for longer than a few minutes, power off and on the VM and try again. If you still cannot get an address at all then something else has gone wrong. We have observed during testing that not removing the "Empty" CD/DVD when setting up the storage can result in this problem; see step 2, above. Another problem is not having the DHCP server enabled for the host-only network; see step 3. 46 | 6. Get the IP address for the BadStore VM. 47 | 48 | From the command prompt in the BadStore VM, execute the command 49 | 50 | It will output network information. Write down the IP address following "inet addr" in the output. It will be something like 192.168.56.110, which is the lower bound configured for the DHCP server in step 3. If you get an error like 51 | 52 | Then this means that your network configuration was messed up; see troubleshooting suggestions in step 5. 53 | 7. Add the BadStore IP address to your non-virtual computer's hosts file. 54 | 55 | To visit the site www.badstore.net being run by your virtual machine, you will have to edit the hosts file on your host (non-virtual, non-guest) computer so that when your host computer's web browser looks up www.badstore.net, it resolves to your virtual machine's address instead of a system on the Internet. If the IP address you wrote down in step 6 was 192.168.56.110, you should add the following on a new line in the hosts file: 56 | 57 | 192.168.56.110 www.badstore.net 58 | 59 | Here are some instructions for finding and editing your hosts file on Windows and Mac OS. For Linux, edit /etc/hosts as root and add the above line (e.g., using the nano editor you could type sudo nano -w /etc/hosts to edit the file). 60 | 8. Point your browser at www.badstore.net. 61 | 62 | It should show the splash page for the BadStore, which displays a black-and-white picture of an old-west-style saloon. If instead your browser hangs, or goes to a different-looking page, then the hosts file is not being accessed correctly. 63 | 64 | Note that if you reboot the BadStore VM, its address may change, so you will have to edit the hosts file again. You should, however, be able to close the running VM, saving its state rather than powering it off. When you restart it, it should restart the network and reconnect using the same address (which you can confirm using the ifconfig command from step 6, above). 65 | Troubleshooting 66 | 67 | If you find that you cannot access BadStore VM, and you are using VMWare, or you get an error from the VM such as "ifconfig: eth0: error fetching interface information: Device not found", try modifying the VM configuration to change the controller for the CD-ROM and hard drive to IDE from SATA (reference link to the forum). 68 | Tools 69 | 70 | You will want to use various tools to interact with BadStore, to inspect and modify the contents of its pages and communications. We recommend some tools here. 71 | Firefox developer tools 72 | 73 | Firefox developer tools give you the ability to inspect and modify the contents of a web page and its communications (from the Developer Tools page, click the DEBUGGING menu item to show the tools you should be most interested in). Developer Tools come pre-installed with recent versions of Firefox; just go to the Web Developer menu to see the possible tools. We will list some useful features here, along with links to the relevant documentation. 74 | 75 | View Source. This is a normal Firefox feature. Right-click on a page you are viewing and then select "View Source" from the menu that appears. A window pops up that gives a complete, syntax-highlighted view of the page source. This view is useful for doing quick searches. For example, use the view to search for hidden form fields (those fields with the attribute "hidden") 76 | 77 | Page Inspector. You can use the page inspector this to examine and modify the structure of a page. Use the source inspector to find pages of interest, and then use the Page inspector to see how the different source elements map to what is displayed, and/or to modify the contents of those pages. 78 | 79 | Developer Toolbar. The Developer Toolbar is a console prompt will allow you to inspect and/or set cookies associated with the current page, among other things. 80 | 81 | Network traffic inspector. While viewing a page in the page inspector, you can click the Network tab to see the network traffic sent or received as a result of interacting with the page. Use this to see cookies sent/received, HTTP headers, request formats, etc. 82 | Other utilities 83 | 84 | Here are other utilities you might find useful: 85 | 86 | Use this on-line utility to decode or encode base64 and other formats 87 | Use this on-line utility to generate cryptographic hashes including MD5, SHA1, and more. 88 | 89 | Exploit! 90 | 91 | Perform exploits on BadStore to find answers to the following questions; once you have, complete the on-line assessment. 92 | 93 | One of the BadStore pages has a hidden form field that establishes a new user's privilege level. What is the name of this field? 94 | How many items for purchase are in BadStore's database? Use SQL injection on the quick search form field to find out. 95 | What operations are suppliers permitted to do once they have logged into the "suppliers only" area? Use SQL injection to bypass authentication, or find a way to create an account as a supplier. 96 | Log in as joe@supplier.com --- this is possible in a variety of ways, including SQL injection. Then look at his previous orders and answer the question: What credit card number did he use to make a purchase of $46.95? Multiple answers are possible, but we will accept all of them. 97 | Get administrator privileges and then use the admin action to look at the user database. There are two users whose emails have the form XXX@whole.biz; what is the XXX portion of either of the two users? For example, if one of the users is jackie@whole.biz, the right answer is jackie. (The answer is case-sensitive.) 98 | BadStore uses cookies to implement a session key, once you've authenticated, and for tracking the contents of the cart, once you've added something to it. You can figure out the cookies in use by BadStore in various ways. One way is to do an XSS attack on the guest book. Get the guest book to run the code and it will tell you the current cookies. (Be sure you have popups enabled on your browser or this won't work.) Alternatively, you can examine the cookies directly using Firefox developer tools. Recall that cookies are pairs key=value. What is the key of the session cookie? 99 | What is the key of the cookie used for the cart? 100 | BadStore's session cookie format is poorly designed because it is uses a predictable structure. In particular, it is an encoded string (with a URL-encoded newline at the end) of the form XXX:YYY:ZZZ:U. What are the XXX, YYY, and ZZZ portions of this string? 101 | BadStore's cart cookie is also an encoded string with a predictable structure XXX:YYY:... etc., and it probably contains information it shouldn't. Which field of the decoded string could an attacker change to give himself a discount on an item's price? 102 | 103 | Tips and Hints 104 | 105 | The BadStore manual has a bunch of hints and tips about exploiting vulnerabilities. 106 | Recall that MySQL comments are two dashes followed by a space (not just two dashes alone). 107 | BadStore generates dynamic HTML using CGI. For example, the URL https://www.badstore.net/cgi-bin/badstore.cgi?action=whatsnew presents a page of "What's new" at BadStore, while the URL https://www.badstore.net/cgi-bin/badstore.cgi?action=viewprevious generates a page showing previous accounts. The only difference between these is what's in the action parameter. Try handcrafted parameters to the various CGI URLs, e.g., ?action=test and ?action=admin. 108 | Ordering from the store should work by just clicking on "Add to Cart" from the "What's new?" page. But this doesn't work if you reach the page via https rather than http; it seems that Firefox blocks the javascript that updates the cart. When you go to the "Supplier Login" area, it will switch you to https and then it will stay that way. You can flip back to http by just changing the URL manually. 109 | Some of the questions require that you get administrator privileges. You can get admin privileges in several ways, including SQL injection (if you can guess the administrator's user ID), spoofing the cookie (per the structure that you glean), or creating a user with administrative rights (using the page with the hidden form field). While normal users have role U administrators have role A. 110 | 111 | Visit http://www.badstore.net/cgi-bin/initdbs.cgi to reset the directories and databases. This is easier than rebooting BadStore, if you want a fresh start. It does not reset your cookies, though. -------------------------------------------------------------------------------- /w3/week-3-quiz: -------------------------------------------------------------------------------- 1 | Week 3 quiz 2 | 3 | 4 | 1. What is one difference between an HTTP GET and an HTTP POST request? 5 | 6 | Only GET requests use the REFERER header 7 | Only POST requests may include parameter data in the request body 8 | Only GET requests are subject to the same-origin policy 9 | Only POST requests can encode parameters in the URL 10 | 11 | 2. Which of the following is true about static and dynamic web content? 12 | 13 | Static pages may include PHP programs, which execute at the browser 14 | The server often produces dynamic content based on the contents of the database 15 | Static content may be re-generated with each request 16 | Javascript programs embedded in HTML pages are run server-side to produce dynamic content 17 | 18 | 3. SQL injection exploits a bug in what interaction of a web application? 19 | 20 | Client to server 21 | Network to server 22 | Server to client 23 | Server to database 24 | 25 | 4. SQL injection often allows an attacker to do which of the following? 26 | 27 | Overrun a buffer to smash the stack 28 | All of the above 29 | Cause memory to be used after it's freed 30 | Access information he shouldn't 31 | 32 | 5. If you had to summarize the key (most specific) programming failure with SQL injection, it would be: 33 | 34 | Confusing data with code 35 | Bypassing authentication 36 | Trusting without verifying 37 | Circumventing the same origin policy 38 | 39 | 6. What is escaping an example of? 40 | 41 | Blacklisting 42 | Sanitization 43 | Checking 44 | Whitelisting 45 | 46 | 7. Suppose a web application implements authentication by constructing an SQL query from HTML from data using PHP's prepared statements. What would happen if an attacker entered FRANK' OR 1=1; -- in the web form's user field? 47 | 48 | The text will modify the structure of the SQL query and possibly bypass authentication 49 | The text will be confused as the password and authentication will probably fail 50 | The text will corrupt the query structure and the database will view it as a syntax error 51 | The application will try to authenticate a user whose name is FRANK' OR 1=1; -- 52 | 53 | 8. Why is it undesirable to implement session identifiers using (only) hidden form fields? 54 | 55 | Such fields cannot include timeout information 56 | Such fields cannot contain binary data 57 | These fields are easily modified by the user 58 | The session ID is forgotten when the browser window is closed 59 | 60 | 9. Suppose a browser submits a GET request to URL http://www.mybank.com/accountinfo on 20 February 2015. Which of the following cookies, if already stored at the browser, would be sent with the request? 61 | 62 | lang=us-english; expires=Sat, 1-Aug-2015; path=/accountinfo/; domain=.fidelity.com 63 | editon=us; expires=Thu, 19-Feb-2015; path=/accountinfo/prefs; domain=.mybank.com 64 | edition=us; expires=Wed, 18-Feb-2015; path=/; domain=.mybank.com 65 | sessid=ABCDEFG; expires=Sat, 21-Feb-2015; path=/; domain=.mybank.com 66 | 67 | 10. Which of the following are ways that session cookies could be stolen or forged? 68 | 69 | Stealing it from the password database 70 | Predicting the cookie's structure and reconstructing it 71 | Reading a cookie from an unencrypted web request 72 | 73 | 11. Which of the following are ways to reduce the impact of a stolen cookies? 74 | 75 | Prevent cookies from entering the DNS cache 76 | Giving each cookie a timeout 77 | Changing a user's cookie from session to session 78 | 79 | 12. How can the REFERER field be used to defend against CSRF attacks? 80 | 81 | It can be used to ensure that sensitive requests are (only) initiated by interaction with a site's own pages 82 | It ensures that requests only come from authenticated users 83 | It can't be used reliably because it only works for dynamic content 84 | It can be used to check that a Javascript program is from the proper origin 85 | 86 | 13. tags in HTML pages most often identify programs written in what language? 87 | 88 | PHP 89 | C 90 | Java 91 | Javascript 92 | 93 | 14. The browser implements security for Javascript programs for what reason? 94 | 95 | Such programs may access browser-controlled resources, which include potentially sensitive data in HTML documents and cookies 96 | It doesn't -- these programs are only used to render dynamic content but are otherwise not security-relevant 97 | Such programs could deny service by running forever 98 | It doesn't -- Javascript programs run at the server so the browser can ignore them 99 | 100 | 15. XSS subverts what policy? 101 | 102 | Whitelisting 103 | Same Origin 104 | Availability 105 | Secure defaults 106 | 107 | 16. What is the difference between stored (or persistent) XSS and reflected XSS? 108 | 109 | Stored XSS works by injecting code in a site's served content, while reflected XSS injects code in a URL 110 | Stored XSS works on database queries while reflected XSS works on cookies, which are received from and reflected back to the server 111 | Stored XSS embeds Javascript in an a URL, while reflected XSS embeds it in a mirrored site 112 | Stored XSS is amenable to blacklisting but reflected XSS is not -------------------------------------------------------------------------------- /w4/1_secure-design-intro.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w4/1_secure-design-intro.pdf -------------------------------------------------------------------------------- /w4/2_threat-modeling.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w4/2_threat-modeling.pdf -------------------------------------------------------------------------------- /w4/3_security-requirements.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w4/3_security-requirements.pdf -------------------------------------------------------------------------------- /w4/4_design-flaws.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w4/4_design-flaws.pdf -------------------------------------------------------------------------------- /w4/5_design-favor-simplicity.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w4/5_design-favor-simplicity.pdf -------------------------------------------------------------------------------- /w4/6_design-trust-reluctantly.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w4/6_design-trust-reluctantly.pdf -------------------------------------------------------------------------------- /w4/7_design-did-mt.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w4/7_design-did-mt.pdf -------------------------------------------------------------------------------- /w4/8_top-design-flaws.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w4/8_top-design-flaws.pdf -------------------------------------------------------------------------------- /w4/week-4-quiz: -------------------------------------------------------------------------------- 1 | Week 4 quiz 2 | 3 | 4 | 1. Why is waiting to think about security until after the software is built a bad idea? 5 | 6 | All of the above 7 | Fixing problems once the software is built is more difficult and more expensive 8 | You might miss important security requirements that necessitate a re-design 9 | You might make critical mistakes in the software's design 10 | 11 | 2. What is an abuse case? 12 | 13 | An official report made by MITRE Corp that describes a discovered software vulnerability and possible abuse of it 14 | A scenario that illustrates a potential failure in security under relevant circumstances 15 | An example of a heated disagreement between the security team and the development team 16 | A scenario that illustrates a system's functional requirements 17 | 18 | 3. Which of the following is a reason to make an explicit threat model when designing a system? 19 | 20 | So that you avoid an incoherent defense 21 | So you can defend against the most likely/costly/important attacks 22 | So you can explicitly list and challenge assumptions that underlie your design 23 | All of the above 24 | 25 | 4. Suppose you design software for a bank and the bank's customers may remotely log into its site using commodity PCs. These PCs might have malware on them, which could log keystrokes or read files stored on the machine. Which threat model (using terms defined in the lectures) makes the most sense for you to consider, when designing the bank's site? 26 | 27 | Malicious user 28 | Co-located user 29 | Network user 30 | Snooping user 31 | 32 | 5. What is a good defense against powers that are particular to a snooping user? 33 | 34 | Using encryption 35 | Using a firewall 36 | Using passwords to authenticate users 37 | Using a type-safe language 38 | 39 | 6. A denial of service attack violates what security policy/goal? 40 | 41 | Integrity 42 | Availability 43 | Authorization 44 | Authentication 45 | 46 | 7. When talking about computer security, what do we mean by the term, principal? 47 | 48 | An actor, or role, that is the subject of a security policy 49 | A rule of thumb for secure coding 50 | A method for delegation 51 | A foundational observation 52 | 53 | 8. Passwords, biometrics, and user-owned SMS-receiving mobile phones are useful for what security mechanism? 54 | 55 | Small trusted computing base (TCB) 56 | Audit 57 | Authorization 58 | Authentication 59 | 60 | 9. We identified several categories of secure design principles, with respect to how they deal with attacks. Running each browser tab in a separate OS process (as done by the Chrome browser) is an example of which category? 61 | 62 | Prevention (of an attack) 63 | Mitigation (of the damage from an attack) 64 | Recovery (from a successful attack) 65 | None of the above 66 | 67 | 10. Suppose you are implementing a graphical user interface for interacting with an implementation of the RSA cryptosystem, and you want to give users a way to generate new keys. Which of the following designs most takes security into account? 68 | 69 | Allow the user to use a slider to choose the number of bits, setting slider initially to point at 2048 bits. As the user moves the slider to larger or smaller values, visualize the difference in relative protective power, e.g., using a meter. 70 | Use a text box to ask the user to fill in how many bits they want their key to be 71 | Don't ask the user about key size at all -- always use 256 bits 72 | Ask the user, but set the default response to be 2048 bits, which is chosen based on the assumption of a strong adversary 73 | 74 | 11. Suppose you are implementing an extensible data management system. You want to accommodate plug-ins that can implement storage rules and query processing functionality for different data formats (e.g., relational data, object data, XML data, etc.). Which of the following designs most takes security into account? 75 | 76 | The plug-ins and the main data management software are linked into the operating system kernel as a special kind of device driver, to give them direct access to stable storage and the network stack, while the OS can enforce their security 77 | 78 | The plug-ins are linked directly in the address space of the data management software, ensuring high performance 79 | 80 | The plug-ins are implemented as separate OS processes; these processes communicate to/from the main process to handle queries/updates for the data formats they support 81 | 82 | The plug-ins are implemented as separate OS processes but which share memory with the main process (and may access its memory as well), for better efficiency. Queries/updates occur via inter-process communication. 83 | 84 | 12. Promoting privacy is a goal that follows from which category of secure design principle? 85 | 86 | It is an example of trusting with reluctance because promoting privacy means sharing private information with as few software components as possible, meaning that fewer need to be trusted to protect the information 87 | 88 | It is an example of defense in depth because privacy is a deep topic that is often debated. 89 | 90 | It is an example of monitoring and recovery because failure to promote privacy could be discovered by monitoring 91 | 92 | It is an example of favoring simplicity because privacy is quite simply the right thing to do 93 | 94 | 13. Encrypting a password database is an example of what category of design principle? 95 | 96 | It is an example of defense in depth 97 | 98 | It is an example of favoring simplicity 99 | 100 | It is an example of monitoring and recovery 101 | 102 | 14. Which of the following vulnerabilities can VSFTPD's secure string library help protect against? 103 | 104 | Privilege escalation 105 | 106 | Buffer overflow 107 | 108 | Integer overflow 109 | 110 | 15. VSFTPD forks a new process to handle each client connection. It could have, instead, spawned a thread within the main process to handle each connection, as is done in many servers. How would this alternative design compare to the original? 111 | 112 | It would be less secure because a compromise by a malicious client in one thread could (more easily) access data used by another client's thread, since they share the same address space 113 | 114 | It would be equally secure and would perform better because threads are cheaper to manage than processes 115 | 116 | It would be more secure because threads are not subject to denial of service attacks but processes are 117 | 118 | It would be more secure because we could apply the SecComp system call to these threads, but could not do so for processes 119 | 120 | 16. FTP servers can be asked to list a directory of files. VSFTPD could do this by calling the system's ls (or dir) command, displaying the result to a client. But VSFTPD does not do this, and implements directory listings using the relevant system calls directly. Why might you argue that VSFTPD's design makes sense from a security perspective? 121 | 122 | ls does more than is needed, and thus unnecessarily expands the TCB 123 | 124 | Calling ls involves forking a new process, which is less secure than running within the same process 125 | 126 | Calling ls doesn't give us any way to employ fail-safe defaults 127 | 128 | Using ls provides less control over the output, which leaves users open to XSS-style attacks 129 | 130 | 131 | -------------------------------------------------------------------------------- /w5/1_static-analysis-intro.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w5/1_static-analysis-intro.pdf -------------------------------------------------------------------------------- /w5/2_static-analysis-overview.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w5/2_static-analysis-overview.pdf -------------------------------------------------------------------------------- /w5/project-3-quiz: -------------------------------------------------------------------------------- 1 | 1. How many iterations does it take the fuzzer to find the bug (i.e., record a crash)? What is the string that it discovers crashes the program? 2 | 3 | ans: 0 4 | 5 | 2. how many iterations? 6 | 7 | ans: 1000 8 | 9 | 3. Name one symbolic variable that was set in the path condition identified by KLEE that crashes wisdom-alt2 10 | 11 | ans: buf 12 | 13 | 4. Name another symbolic variable set in the path condition identified by KLEE that crashes wisdom-alt2. 14 | 15 | ans: r 16 | 17 | 5. Which symbolic variables were involved (AAAAAA and BBBBBB in the above)? 18 | 19 | ans: buf, \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 20 | 21 | 6. What was their contents (XXXXXXXX in the above)? 22 | 23 | ans: \x00\x00\x00\x00 24 | 25 | 7. What was the data (the XXXXetc. part, not including any \x00\x00 parts, if any) for the program object? 26 | 27 | ans: sddwddddssssddwwww 28 | 29 | 8. If you run the symbolic maze program so that it finds all solutions, not just one, how many are there? 30 | 31 | ans: 4 32 | 33 | 9. There was a bug in the maze program that allows the player to walk through walls. What line in maze-sym.c is the bug on? (If there are multiple lines, pick one of them.) 34 | 35 | ans: 113 -------------------------------------------------------------------------------- /w5/project-3-quiz1: -------------------------------------------------------------------------------- 1 | Project 3 quiz 2 | 3 | 1. Does fuzz.py identify a crash in wisdom-alt? In how many iterations? 4 | 5 | Identifies a crash, 44 iterations 6 | 7 | Does not identify a crash 8 | 9 | Identifies a crash, 103 iterations 10 | 11 | Identifies a crash, one iteration 12 | 13 | 2. Does fuzz.py identify a crash in wisdom-alt2? In how many iterations? 14 | 15 | Does not identify a crash 16 | 17 | Identifies a crash, 133 iterations 18 | 19 | Identifies a crash, 800 iterations 20 | 21 | Identifies a crash, 1 iteration 22 | 23 | 3. Name one symbolic variable that was set in the path condition identified by KLEE that crashes wisdom-alt2. 24 | 25 | Enter answer here 26 | 27 | 4. Name another symbolic variable set in the path condition identified by KLEE that crashes wisdom-alt2. 28 | 29 | Enter answer here 30 | 31 | 5. What was the data content of the buf object? 32 | 33 | '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xAA' 34 | 35 | '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' 36 | 37 | '\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' 38 | 39 | '\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\xBB\x00\x00\x00\x00\x00\x00\x00\x00\xEE' 40 | 41 | 6. After executing the symbolic maze, what was the data value of the 'program' object? (Hint: it will be a string of the lowercase letters s, d, w, and a.) 42 | 43 | Enter answer here 44 | 45 | 7. If you run the symbolic maze program so that it finds all solutions, not just one, how many are there? 46 | 47 | Enter answer here 48 | 49 | 8. There was a bug in the maze program that allows the player to walk through walls. What line in maze-sym.c is the bug on? (If there are multiple lines, pick one of them.) 50 | 51 | Enter answer here 52 | 53 | 54 | -------------------------------------------------------------------------------- /w5/project-3/info: -------------------------------------------------------------------------------- 1 | White Box and Black Box Fuzz Testing 2 | 3 | Week 5 presents static analysis and symbolic execution as two techniques for automatically finding security bugs (and other bugs) in programs. 4 | 5 | In this lab, we will play with a symbolic executor called KLEE, an open source symbolic execution engine built on top of the LLVM compiler framework. We will compare KLEE's ability to find memory errors to that of black box fuzzing tool, called radamsa that we see a bit more during week 6. 6 | 7 | We will see that the symbolic executor is able to systematically explore the different control paths of the program, including paths that a black box tool may have difficulty finding. As such, symbolic executors are sometimes called "white box fuzz testers." 8 | Setup 9 | 10 | We will be re-using the VM from Project 1. If you did not download that VM, or you have since erased it, directions for installation can be found on the Project 1 page. 11 | 12 | We have installed KLEE as a self-contained package in the klee-cde-package sub-directory of the seed user's home directory. To use the KLEE binaries we will set your PATH, below, to include the bin directory, which is a sub-directory of the root of the KLEE package. Note that because we've installed the cde version of the package, to run the KLEE executables you'll need to add .cde to the end of each executable name, e.g., llvm-gcc.cde and klee.cde. We installed radamsa in the usual place (/usr/bin). 13 | 14 | We have created modified versions of the project 1 files, as well as some other scripts to help with this lab. They are in the folder projects/3 (from the home directory) on the project 1 VM. Enter this directory, and run the following commands. 15 | 16 | $ make wisdom-alt 17 | $ make wisdom-alt2 18 | 19 | These will build the wisdom-alt and wisdom-alt2 executables in this directory. 20 | 21 | Run all the following examples from this directory. Now go through each of the steps below, noting your answers, and then take the project quiz. 22 | 23 | The project 3 files should also be available in this archive https://d396qusza40orc.cloudfront.net/softwaresec/projects.zip, if you want to download them directly. 24 | 25 | Question 1: Fuzzing 26 | 27 | Radamsa is a fuzzer that generates random program inputs by mutating some given input. We have provided a Python script, called fuzz.py that connects the output from radamsa to the input of the wisdom program. Radamsa must start with some data to mutate, this data is contained in the fuzzinput file. 28 | 29 | Execute the fuzzer against wisdom-alt. Use the command line: 30 | 31 | $ python fuzz.py ./wisdom-alt > out && tail out 32 | 33 | (This runs the fuzzing program to completion, storing its output in the file out, and then presenting the last bit of that file. Hit Ctrl-C to get back to the command line.) 34 | 35 | How many iterations does it take the fuzzer to find the bug (i.e., record a crash)? What is the string that it discovers crashes the program? 36 | 37 | See what happens if you change fuzzinput to something else and then rerun. Or, try editing fuzz.py and change the seed that is given to radamsa to generate different inputs, to see how that might change things. 38 | 39 | Question 2: Fuzzing alt2 40 | 41 | The wisdom-alt2.c file is the same as wisdom-alt.c file except that we have added an additional guard restricting the values that can index into ptrs. 42 | 43 | $ diff wisdom-alt.c wisdom-alt2.c 44 | 101,102c101,104 45 | < fptr tmp = ptrs[s]; 46 | < tmp(); 47 | --- 48 | > if(s == 1 || s == 2) { 49 | > fptr tmp = ptrs[s]; 50 | > tmp(); 51 | > } 52 | 53 | This change fixes the bug you found in Project 1, by only permitting 1 or 2 to be legal inputs. The question is, How does this impact the effectiveness of the fuzzer? 54 | 55 | $ python fuzz.py ./wisdom-alt2 > out && tail out 56 | 57 | Does this find the bug, i.e. record a crash? If so, in how many iterations? 58 | 59 | Once again, you can adjust the seed value in the script, or try more iterations, to see what happens. (But to answer this question for the quiz leave the seed and iteration count at what they were in the download.) 60 | 61 | Question 3: Symbolically executing wisdom-alt2 62 | 63 | Now let's try symbolic execution on the program instead. To do this, we have to modify the program to identify which variables KLEE should consider to be symbolic. We also have to make some other cosmetic changes to get things to work properly. The result is in the file wisdom-alt-sym.c. 64 | 65 | You can do diff wisdom-alt2.c wisdom-alt-sym.c to see the differences for yourself, but here's a summary. First, we added a function sym_gets that simulates the gets library call by filling a buffer with symbolic values, and replace the program's call to gets with a call to this function. Second, we removed the loop that repeatedly requests user input; this speeds up our testing because we only need one input to find the bug, and KLEE will repeatedly explore different (single) inputs. Third, we replaced the command to read the initial input, read(infd, buf, sizeof(buf)-sizeof(char)); to instead ask KLEE to generate a symbolic value, using klee_make_symbolic(buf, sizeof(buf), "buf"); 66 | 67 | Now compile the wisdom-alt-sym program with the following command line (from within the project3 directory): 68 | 69 | $ export PATH=$HOME/klee-cde-package/bin/:$PATH 70 | $ llvm-gcc.cde -I../../klee-cde-package/cde-root/home/pgbovine/klee/include --emit-llvm -c -g wisdom-alt-sym.c 71 | 72 | (Note that the first option is an uppercase I, not a lowercase L.) Now evaluate it with KLEE using the following command line: 73 | 74 | $ klee.cde -exit-on-error wisdom-alt-sym.o 75 | 76 | It should exit shortly and discover the error, printing a stack trace and some information about the current state. It will have created a directory klee-last in the current directory that contains further information about the symbolic execution. If you look in there, you will see that it generated some tests and some statistics. 77 | 78 | The (binary) files ending in .ktest in this directory can be formatted intelligibly by using ktest-tool. Use the following command line to discover the symbolic state the error occurred in: 79 | 80 | $ ktest-tool.cde klee-last/test000001.ktest 81 | ktest file : 'klee-last/test000001.ktest' 82 | args : ['wisdom-alt-sym.o'] 83 | num objects: 2 84 | object 0: name: 'AAAAAA' 85 | object 0: size: NN 86 | object 0: data: 'XXXXXXXX' 87 | object 1: name: 'BBBBBBB' 88 | object 1: size: JJ 89 | object 1: data: 'XXXXXXXX' 90 | 91 | We have replaced particular values in the above output with AAA, NN, etc. Which symbolic variables were involved (AAAAAA and BBBBBB in the above)? What was their contents (XXXXXXXX in the above)? 92 | 93 | Question 4: Symbolically executing the maze 94 | 95 | In a sense, a symbolic executor is exploring a maze defined by the program's execution space. We can make this analogy a reality by using KLEE to symbolically execute a program that asks its user to solve a maze. This program is taken from a blog post by Felipe Andres Manzano; I encourage you to check it out to go into more depth about what's going on. 96 | 97 | The file maze.c defines the maze-solving program, and the file maze-sym.c is a slightly modified version of it, suitable for running with KLEE. Compile the maze programs both normally and symbolically: 98 | 99 | $ make maze 100 | $ llvm-gcc.cde -I ../../klee-cde-package/cde-root/home/pgbovine/klee/include --emit-llvm -c -g maze-sym.c 101 | 102 | Once again, the second version is different from the first in identifying data as symbolic. 103 | 104 | $ diff maze.c maze-sym.c 105 | 10a11 106 | > #include 107 | 71c72,73 108 | < read(0,program,ITERS); 109 | --- 110 | > //read(0,program,ITERS); 111 | > klee_make_symbolic(program,ITERS,"program"); 112 | 113 | Here, the variable program is a buffer that contains the user's input; instead of reading it in from the user, the modified program treats the entire buffer as symbolic. 114 | 115 | Run the (normal) maze program and see if you can find a solution to the maze. Then, run the symbolic maze program under KLEE: 116 | 117 | $ klee.cde maze-sym.o 118 | 119 | KLEE will work for a while and then end. The maze program will generate an assertion failure when a path through the maze has been identified, so the test that is a winning path through the maze is identified by an assert. Look for the path that solved the maze looking for a file that ends in err: 120 | 121 | $ ls -1 klee-last | grep -A2 -B2 err 122 | test0000AA.ktest 123 | test0000BB.ktest 124 | test0000NN.assert.err 125 | test0000NN.ktest 126 | test0000NN.pc 127 | 128 | (Note the argument to ls is a 1 (one), not a lower-case l.) Here, AA, BB, and NN are numbers that may change depending on your VM setup (on mine, NN is sometimes 62 and sometimes 89). Use the ktest-tool on the test0000NN.ktest file (where NN is replaced with numbers from your VM) to see what path KLEE found through the maze. 129 | 130 | $ ktest-tool.cde klee-last/test0000NN.ktest 131 | ktest file : 'klee-last/test0000NN.ktest' 132 | args : ['maze-sym.o'] 133 | num objects: 1 134 | object 0: name: 'program' 135 | object 0: size: MM 136 | object 0: data: 'XXXXXXXXXXXXXXXXXXXXXXXXX\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' 137 | 138 | What was the data (the XXXXetc. part, not including any \x00\x00 parts, if any) for the program object? 139 | 140 | It turns out there are multiple "solutions" to the maze; you can see them all by doing 141 | 142 | $ klee.cde --emit-all-errors maze-sym.o 143 | 144 | Then the ls command from above will show all the solutions. How many are there? 145 | 146 | Question 5: Walking through walls 147 | 148 | Are you surprised by the answer to question 4? 149 | 150 | Something funny is going on: somehow the solution is allowed to walk through walls. Look through the code, and find the condition that allows this to happen. What line is it on? Comment it out and try again, to confirm you are getting just one solution. -------------------------------------------------------------------------------- /w5/project-3/projects/1/runbin.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | while read -r line; do echo -e $line; done | ./wisdom-alt 3 | -------------------------------------------------------------------------------- /w5/project-3/projects/1/wisdom-alt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w5/project-3/projects/1/wisdom-alt -------------------------------------------------------------------------------- /w5/project-3/projects/1/wisdom-alt.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | char greeting[] = "Hello there\n1. Receive wisdom\n2. Add wisdom\nSelection >"; 10 | char prompt[] = "Enter some wisdom\n"; 11 | char pat[] = "Achievement unlocked!\n"; 12 | char secret[] = "secret key"; 13 | 14 | int infd = 0; /* stdin */ 15 | int outfd = 1; /* stdout */ 16 | 17 | #define DATA_SIZE 128 18 | 19 | typedef struct _WisdomList { 20 | struct _WisdomList *next; 21 | char data[DATA_SIZE]; 22 | } WisdomList; 23 | 24 | struct _WisdomList *head = NULL; 25 | 26 | typedef void (*fptr)(void); 27 | 28 | void write_secret(void) { 29 | write(outfd, secret, sizeof(secret)); 30 | return; 31 | } 32 | 33 | void pat_on_back(void) { 34 | write(outfd, pat, sizeof(pat)); 35 | return; 36 | } 37 | 38 | void get_wisdom(void) { 39 | char buf[] = "no wisdom\n"; 40 | if(head == NULL) { 41 | write(outfd, buf, sizeof(buf)-sizeof(char)); 42 | } else { 43 | WisdomList *l = head; 44 | while(l != NULL) { 45 | write(outfd, l->data, strlen(l->data)); 46 | write(outfd, "\n", 1); 47 | l = l->next; 48 | } 49 | } 50 | return; 51 | } 52 | 53 | void put_wisdom(void) { 54 | char wis[DATA_SIZE] = {0}; 55 | int r; 56 | 57 | r = write(outfd, prompt, sizeof(prompt)-sizeof(char)); 58 | if(r < 0) { 59 | return; 60 | } 61 | 62 | r = (int)gets(wis); 63 | if (r == 0) 64 | return; 65 | 66 | WisdomList *l = malloc(sizeof(WisdomList)); 67 | 68 | if(l != NULL) { 69 | memset(l, 0, sizeof(WisdomList)); 70 | strcpy(l->data, wis); 71 | if(head == NULL) { 72 | head = l; 73 | } else { 74 | WisdomList *v = head; 75 | while(v->next != NULL) { 76 | v = v->next; 77 | } 78 | v->next = l; 79 | } 80 | } 81 | 82 | return; 83 | } 84 | 85 | fptr ptrs[3] = { NULL, get_wisdom, put_wisdom }; 86 | 87 | int main(int argc, char *argv[]) { 88 | 89 | while(1) { 90 | char buf[1024] = {0}; 91 | int r; 92 | fptr p = pat_on_back; 93 | r = write(outfd, greeting, sizeof(greeting)-sizeof(char)); 94 | if(r < 0) { 95 | break; 96 | } 97 | r = read(infd, buf, sizeof(buf)-sizeof(char)); 98 | if(r > 0) { 99 | buf[r] = '\0'; 100 | int s = atoi(buf); 101 | fptr tmp = ptrs[s]; 102 | tmp(); 103 | } else { 104 | break; 105 | } 106 | } 107 | 108 | return 0; 109 | } 110 | -------------------------------------------------------------------------------- /w5/project-3/projects/3/fuzz.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | from time import sleep 3 | import sys 4 | 5 | fuzzee = subprocess.Popen([sys.argv[1]],stdout=subprocess.PIPE,stderr=subprocess.PIPE,stdin=subprocess.PIPE) 6 | 7 | enterWis = False 8 | iter = 0 9 | max = 1000 10 | seed = 12458341 11 | while fuzzee.returncode == None and iter < max: 12 | print "%d/%d" % (iter,max) 13 | #get fuzz input 14 | fuzzer = subprocess.Popen(["radamsa", "-s", str(seed), "fuzzinput"],stdout=subprocess.PIPE) 15 | seed = seed + 1 16 | inp, err = fuzzer.communicate() 17 | print "trying %s" % inp 18 | out = "" 19 | while True: 20 | c = fuzzee.stdout.read(1) 21 | out = out + c 22 | if c == ">": 23 | enterWis = False 24 | break 25 | r = out.find("Enter some wisdom") 26 | if r >= 0: 27 | enterWis = True 28 | break 29 | fuzzee.stdout.flush() 30 | fuzzee.stdin.flush() 31 | if enterWis == False: 32 | fuzzee.stdin.write("%s\n" % inp) 33 | else: 34 | fuzzee.stdin.write("%s\n" % inp) 35 | fuzzee.stdin.flush() 36 | fuzzee.poll() 37 | iter = iter + 1 38 | 39 | if fuzzee.returncode == None: 40 | print "did not crash" 41 | else: 42 | print "crashed with %s" % inp 43 | -------------------------------------------------------------------------------- /w5/project-3/projects/3/fuzzinput: -------------------------------------------------------------------------------- 1 | 1aaaaaaaa 2 | -------------------------------------------------------------------------------- /w5/project-3/projects/3/maze-sym.c: -------------------------------------------------------------------------------- 1 | // http://feliam.wordpress.com/2010/10/07/the-symbolic-maze/ ‎ 2 | // twitter.com/feliam 3 | /* 4 | * It's a maze! 5 | * Use a,s,d,w to move "through" it. 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | /** 14 | * Maze hardcoded dimensions 15 | */ 16 | #define H 7 17 | #define W 11 18 | /** 19 | * Tha maze map 20 | */ 21 | char maze[H][W] = { "+-+---+---+", 22 | "| | |#|", 23 | "| | --+ | |", 24 | "| | | | |", 25 | "| +-- | | |", 26 | "| | |", 27 | "+-----+---+" }; 28 | 29 | /** 30 | * Draw the maze state in the screen! 31 | */ 32 | void draw () 33 | { 34 | int i, j; 35 | for (i = 0; i < H; i++) 36 | { 37 | for (j = 0; j < W; j++) 38 | printf ("%c", maze[i][j]); 39 | printf ("\n"); 40 | } 41 | printf ("\n"); 42 | } 43 | 44 | 45 | /** 46 | * The main function 47 | */ 48 | int 49 | main (int argc, char *argv[]) 50 | { 51 | int x, y; //Player position 52 | int ox, oy; //Old player position 53 | int i = 0; //Iteration number 54 | #define ITERS 28 55 | char program[ITERS]; 56 | 57 | //Initial position 58 | x = 1; 59 | y = 1; 60 | maze[y][x]='X'; 61 | 62 | //Print some info 63 | printf ("Maze dimensions: %dx%d\n", W, H); 64 | printf ("Player pos: %dx%d\n", x, y); 65 | printf ("Iteration no. %d\n",i); 66 | printf ("Program the player moves with a sequence of 'w', 's', 'a' and 'd'\n"); 67 | printf ("Try to reach the price(#)!\n"); 68 | 69 | //Draw the maze 70 | draw (); 71 | //Read the directions 'program' to execute... 72 | //read(0,program,ITERS); 73 | klee_make_symbolic(program,ITERS,"program"); 74 | 75 | //Iterate and run 'program' 76 | while(i < ITERS) 77 | { 78 | //Save old player position 79 | ox = x; 80 | oy = y; 81 | //Move polayer position depending on the actual command 82 | switch (program[i]) 83 | { 84 | case 'w': 85 | y--; 86 | break; 87 | case 's': 88 | y++; 89 | break; 90 | case 'a': 91 | x--; 92 | break; 93 | case 'd': 94 | x++; 95 | break; 96 | default: 97 | printf("Wrong command!(only w,s,a,d accepted!)\n"); 98 | printf("You loose!\n"); 99 | exit(-1); 100 | } 101 | 102 | //If hit the price, You Win!! 103 | if (maze[y][x] == '#') 104 | { 105 | printf ("You win!\n"); 106 | printf ("Your solution <%42s>\n",program); 107 | klee_assert(0); 108 | exit (1); 109 | } 110 | //If something is wrong do not advance 111 | if (maze[y][x] != ' ' 112 | && 113 | !((y == 2 && maze[y][x] == '|' && x > 0 && x < W))) 114 | { 115 | x = ox; 116 | y = oy; 117 | } 118 | 119 | //Print new maze state and info... 120 | printf ("Player pos: %dx%d\n", x, y); 121 | printf ("Iteration no. %d. Action: %c. %s\n",i,program[i], ((ox==x && oy==y)?"Blocked!":"")); 122 | 123 | //If crashed to a wall! Exit, you loose 124 | if (ox==x && oy==y){ 125 | printf("You loose\n"); 126 | exit(-2); 127 | } 128 | //put the player on the maze... 129 | maze[y][x]='X'; 130 | //draw it 131 | draw (); 132 | //increment iteration 133 | i++; 134 | //me wait to human 135 | sleep(1); 136 | } 137 | //You couldn't make it! You loose! 138 | printf("You loose\n"); 139 | } 140 | -------------------------------------------------------------------------------- /w5/project-3/projects/3/maze.c: -------------------------------------------------------------------------------- 1 | // http://feliam.wordpress.com/2010/10/07/the-symbolic-maze/ ‎ 2 | // twitter.com/feliam 3 | /* 4 | * It's a maze! 5 | * Use a,s,d,w to move "through" it. 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | /** 13 | * Maze hardcoded dimensions 14 | */ 15 | #define H 7 16 | #define W 11 17 | /** 18 | * Tha maze map 19 | */ 20 | char maze[H][W] = { "+-+---+---+", 21 | "| | |#|", 22 | "| | --+ | |", 23 | "| | | | |", 24 | "| +-- | | |", 25 | "| | |", 26 | "+-----+---+" }; 27 | 28 | /** 29 | * Draw the maze state in the screen! 30 | */ 31 | void draw () 32 | { 33 | int i, j; 34 | for (i = 0; i < H; i++) 35 | { 36 | for (j = 0; j < W; j++) 37 | printf ("%c", maze[i][j]); 38 | printf ("\n"); 39 | } 40 | printf ("\n"); 41 | } 42 | 43 | 44 | /** 45 | * The main function 46 | */ 47 | int 48 | main (int argc, char *argv[]) 49 | { 50 | int x, y; //Player position 51 | int ox, oy; //Old player position 52 | int i = 0; //Iteration number 53 | #define ITERS 28 54 | char program[ITERS]; 55 | 56 | //Initial position 57 | x = 1; 58 | y = 1; 59 | maze[y][x]='X'; 60 | 61 | //Print some info 62 | printf ("Maze dimensions: %dx%d\n", W, H); 63 | printf ("Player pos: %dx%d\n", x, y); 64 | printf ("Iteration no. %d\n",i); 65 | printf ("Program the player moves with a sequence of 'w', 's', 'a' and 'd'\n"); 66 | printf ("Try to reach the price(#)!\n"); 67 | 68 | //Draw the maze 69 | draw (); 70 | //Read the directions 'program' to execute... 71 | read(0,program,ITERS); 72 | 73 | //Iterate and run 'program' 74 | while(i < ITERS) 75 | { 76 | //Save old player position 77 | ox = x; 78 | oy = y; 79 | //Move polayer position depending on the actual command 80 | switch (program[i]) 81 | { 82 | case 'w': 83 | y--; 84 | break; 85 | case 's': 86 | y++; 87 | break; 88 | case 'a': 89 | x--; 90 | break; 91 | case 'd': 92 | x++; 93 | break; 94 | default: 95 | printf("Wrong command!(only w,s,a,d accepted!)\n"); 96 | printf("You loose!\n"); 97 | exit(-1); 98 | } 99 | 100 | //If hit the price, You Win!! 101 | if (maze[y][x] == '#') 102 | { 103 | printf ("You win!\n"); 104 | printf ("Your solution <%42s>\n",program); 105 | exit (1); 106 | } 107 | //If something is wrong do not advance 108 | if (maze[y][x] != ' ' 109 | && 110 | !((y == 2 && maze[y][x] == '|' && x > 0 && x < W))) 111 | { 112 | x = ox; 113 | y = oy; 114 | } 115 | 116 | //Print new maze state and info... 117 | printf ("Player pos: %dx%d\n", x, y); 118 | printf ("Iteration no. %d. Action: %c. %s\n",i,program[i], ((ox==x && oy==y)?"Blocked!":"")); 119 | 120 | //If crashed to a wall! Exit, you loose 121 | if (ox==x && oy==y){ 122 | printf("You loose\n"); 123 | exit(-2); 124 | } 125 | //put the player on the maze... 126 | maze[y][x]='X'; 127 | //draw it 128 | draw (); 129 | //increment iteration 130 | i++; 131 | //me wait to human 132 | sleep(1); 133 | } 134 | //You couldn't make it! You loose! 135 | printf("You loose\n"); 136 | } 137 | -------------------------------------------------------------------------------- /w5/project-3/projects/3/wisdom-alt-sym.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | char greeting[] = "Hello there\n1. Receive wisdom\n2. Add wisdom\nSelection >"; 11 | char prompt[] = "Enter some wisdom\n"; 12 | char pat[] = "Achievement unlocked!\n"; 13 | char secret[] = "secret key"; 14 | 15 | int infd = 0; /* stdin */ 16 | int outfd = 1; /* stdout */ 17 | 18 | #define DATA_SIZE 128 19 | 20 | typedef struct _WisdomList { 21 | struct _WisdomList *next; 22 | char data[DATA_SIZE]; 23 | } WisdomList; 24 | 25 | struct _WisdomList *head = NULL; 26 | 27 | typedef void (*fptr)(void); 28 | 29 | void write_secret(void) { 30 | write(outfd, secret, sizeof(secret)); 31 | return; 32 | } 33 | 34 | void pat_on_back(void) { 35 | write(outfd, pat, sizeof(pat)); 36 | return; 37 | } 38 | 39 | void get_wisdom(void) { 40 | char buf[] = "no wisdom\n"; 41 | if(head == NULL) { 42 | write(outfd, buf, sizeof(buf)-sizeof(char)); 43 | } else { 44 | WisdomList *l = head; 45 | while(l != NULL) { 46 | write(outfd, l->data, strlen(l->data)); 47 | write(outfd, "\n", 1); 48 | l = l->next; 49 | } 50 | } 51 | return; 52 | } 53 | 54 | //simulates symoblic outside input 55 | int sym_gets(char *buf) { 56 | int r = 0; 57 | char *ptr = buf; 58 | while(1) { 59 | r = klee_range(0, 255, "input"); 60 | *ptr = r; 61 | ptr++; 62 | if(r == 0) { 63 | break; 64 | } 65 | } 66 | 67 | return r; 68 | } 69 | 70 | void put_wisdom(void) { 71 | char wis[DATA_SIZE] = {0}; 72 | int r; 73 | char *ptr; 74 | 75 | r = write(outfd, prompt, sizeof(prompt)-sizeof(char)); 76 | if(r < 0) { 77 | return; 78 | } 79 | 80 | r = sym_gets(wis); 81 | if (r == 0) 82 | return; 83 | 84 | WisdomList *l = malloc(sizeof(WisdomList)); 85 | 86 | if(l != NULL) { 87 | memset(l, 0, sizeof(WisdomList)); 88 | strcpy(l->data, wis); 89 | if(head == NULL) { 90 | head = l; 91 | } else { 92 | WisdomList *v = head; 93 | while(v->next != NULL) { 94 | v = v->next; 95 | } 96 | v->next = l; 97 | } 98 | } 99 | 100 | return; 101 | } 102 | 103 | fptr ptrs[2] = { get_wisdom, put_wisdom }; 104 | 105 | int main(int argc, char *argv[]) { 106 | 107 | //while(1) { 108 | char buf[20] = {0}; 109 | int r; 110 | fptr p = pat_on_back; 111 | r = write(outfd, greeting, sizeof(greeting)-sizeof(char)); 112 | if(r < 0) { 113 | return 0; 114 | } 115 | //r = read(infd, buf, sizeof(buf)-sizeof(char)); 116 | klee_make_symbolic(buf, sizeof(buf), "buf"); 117 | r = klee_range(-1, sizeof(buf), "r"); 118 | if(r > 0) { 119 | buf[r] = '\0'; 120 | int s = klee_range(0, 255, "v"); 121 | if(s == 0 || s == 1) { 122 | fptr tmp = ptrs[s]; 123 | tmp(); 124 | } 125 | } else { 126 | return 0; 127 | } 128 | //} 129 | 130 | return 0; 131 | } 132 | -------------------------------------------------------------------------------- /w5/project-3/projects/3/wisdom-alt.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | char greeting[] = "Hello there\n1. Receive wisdom\n2. Add wisdom\nSelection >"; 10 | char prompt[] = "Enter some wisdom\n"; 11 | char pat[] = "Achievement unlocked!\n"; 12 | char secret[] = "secret key"; 13 | 14 | int infd = 0; /* stdin */ 15 | int outfd = 1; /* stdout */ 16 | 17 | #define DATA_SIZE 128 18 | 19 | typedef struct _WisdomList { 20 | struct _WisdomList *next; 21 | char data[DATA_SIZE]; 22 | } WisdomList; 23 | 24 | struct _WisdomList *head = NULL; 25 | 26 | typedef void (*fptr)(void); 27 | 28 | void write_secret(void) { 29 | write(outfd, secret, sizeof(secret)); 30 | return; 31 | } 32 | 33 | void pat_on_back(void) { 34 | write(outfd, pat, sizeof(pat)); 35 | return; 36 | } 37 | 38 | void get_wisdom(void) { 39 | char buf[] = "no wisdom\n"; 40 | if(head == NULL) { 41 | write(outfd, buf, sizeof(buf)-sizeof(char)); 42 | } else { 43 | WisdomList *l = head; 44 | while(l != NULL) { 45 | write(outfd, l->data, strlen(l->data)); 46 | write(outfd, "\n", 1); 47 | l = l->next; 48 | } 49 | } 50 | return; 51 | } 52 | 53 | void put_wisdom(void) { 54 | char wis[DATA_SIZE] = {0}; 55 | int r; 56 | 57 | r = write(outfd, prompt, sizeof(prompt)-sizeof(char)); 58 | if(r < 0) { 59 | return; 60 | } 61 | 62 | r = (int)gets(wis); 63 | if (r == 0) 64 | return; 65 | 66 | WisdomList *l = malloc(sizeof(WisdomList)); 67 | 68 | if(l != NULL) { 69 | memset(l, 0, sizeof(WisdomList)); 70 | strcpy(l->data, wis); 71 | if(head == NULL) { 72 | head = l; 73 | } else { 74 | WisdomList *v = head; 75 | while(v->next != NULL) { 76 | v = v->next; 77 | } 78 | v->next = l; 79 | } 80 | } 81 | 82 | return; 83 | } 84 | 85 | fptr ptrs[3] = { NULL, get_wisdom, put_wisdom }; 86 | 87 | int main(int argc, char *argv[]) { 88 | 89 | while(1) { 90 | char buf[1024] = {0}; 91 | int r; 92 | fptr p = pat_on_back; 93 | r = write(outfd, greeting, sizeof(greeting)-sizeof(char)); 94 | if(r < 0) { 95 | break; 96 | } 97 | r = read(infd, buf, sizeof(buf)-sizeof(char)); 98 | if(r > 0) { 99 | buf[r] = '\0'; 100 | int s = atoi(buf); 101 | fptr tmp = ptrs[s]; 102 | tmp(); 103 | } else { 104 | break; 105 | } 106 | } 107 | 108 | return 0; 109 | } 110 | -------------------------------------------------------------------------------- /w5/project-3/projects/3/wisdom-alt2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | char greeting[] = "Hello there\n1. Receive wisdom\n2. Add wisdom\nSelection >"; 10 | char prompt[] = "Enter some wisdom\n"; 11 | char pat[] = "Achievement unlocked!\n"; 12 | char secret[] = "secret key"; 13 | 14 | int infd = 0; /* stdin */ 15 | int outfd = 1; /* stdout */ 16 | 17 | #define DATA_SIZE 128 18 | 19 | typedef struct _WisdomList { 20 | struct _WisdomList *next; 21 | char data[DATA_SIZE]; 22 | } WisdomList; 23 | 24 | struct _WisdomList *head = NULL; 25 | 26 | typedef void (*fptr)(void); 27 | 28 | void write_secret(void) { 29 | write(outfd, secret, sizeof(secret)); 30 | return; 31 | } 32 | 33 | void pat_on_back(void) { 34 | write(outfd, pat, sizeof(pat)); 35 | return; 36 | } 37 | 38 | void get_wisdom(void) { 39 | char buf[] = "no wisdom\n"; 40 | if(head == NULL) { 41 | write(outfd, buf, sizeof(buf)-sizeof(char)); 42 | } else { 43 | WisdomList *l = head; 44 | while(l != NULL) { 45 | write(outfd, l->data, strlen(l->data)); 46 | write(outfd, "\n", 1); 47 | l = l->next; 48 | } 49 | } 50 | return; 51 | } 52 | 53 | void put_wisdom(void) { 54 | char wis[DATA_SIZE] = {0}; 55 | int r; 56 | 57 | r = write(outfd, prompt, sizeof(prompt)-sizeof(char)); 58 | if(r < 0) { 59 | return; 60 | } 61 | 62 | r = (int)gets(wis); 63 | if (r == 0) 64 | return; 65 | 66 | WisdomList *l = malloc(sizeof(WisdomList)); 67 | 68 | if(l != NULL) { 69 | memset(l, 0, sizeof(WisdomList)); 70 | strcpy(l->data, wis); 71 | if(head == NULL) { 72 | head = l; 73 | } else { 74 | WisdomList *v = head; 75 | while(v->next != NULL) { 76 | v = v->next; 77 | } 78 | v->next = l; 79 | } 80 | } 81 | 82 | return; 83 | } 84 | 85 | fptr ptrs[3] = { NULL, get_wisdom, put_wisdom }; 86 | 87 | int main(int argc, char *argv[]) { 88 | 89 | while(1) { 90 | char buf[1024] = {0}; 91 | int r; 92 | fptr p = pat_on_back; 93 | r = write(outfd, greeting, sizeof(greeting)-sizeof(char)); 94 | if(r < 0) { 95 | break; 96 | } 97 | r = read(infd, buf, sizeof(buf)-sizeof(char)); 98 | if(r > 0) { 99 | buf[r] = '\0'; 100 | int s = atoi(buf); 101 | if(s == 1 || s == 2) { 102 | fptr tmp = ptrs[s]; 103 | tmp(); 104 | } 105 | } else { 106 | break; 107 | } 108 | } 109 | 110 | return 0; 111 | } 112 | -------------------------------------------------------------------------------- /w5/week-5-quiz: -------------------------------------------------------------------------------- 1 | Week 5 quiz 2 | 3 | 4 | 1. A static analysis 5 | 6 | is a kind of real analysis for solving numeric equations 7 | 8 | analyzes the fixed, or static portions of a program 9 | 10 | is always better than testing 11 | 12 | analyzes a program's code without running it 13 | 14 | 2. Which of the following are advantages of static analysis over testing? 15 | 16 | A static analysis runs faster than testing 17 | 18 | A static analysis is more precise than testing 19 | 20 | A static analysis can analyze programs that are not necessarily executable on their own, e.g., libraries 21 | 22 | 3. The halting problem is the problem of determining, for an arbitrary program and input, whether the program will finish running or continue to run forever. Which of the following statements about the halting problem are true? 23 | 24 | You cannot build an automated analysis that proves that a particular program P terminates. 25 | 26 | Many other program analysis problems can be converted to the halting problem. 27 | 28 | You cannot solve the halting problem with static analysis, but you can with symbolic execution. 29 | 30 | 4. Suppose we have a static analysis that aims to find buffer overflows in C programs. If the analysis is sound, then which of the following is true about it? 31 | 32 | It may have false alarms, but will not fail to report actual bugs 33 | 34 | It will not have any false alarms, but may fail to report actual bugs 35 | 36 | It will report all actual bugs, and have no false alarms 37 | 38 | It may miss bugs, and have false alarms 39 | 40 | 5. A tainted flow is 41 | 42 | A flow from an untrusted source to both trusted and untrusted sinks 43 | 44 | A flow from an untrusted source to a trusted sink 45 | 46 | A flow from a trusted source to an untrusted sink 47 | 48 | A flow from a trusted source to both trusted and untrusted sinks 49 | 50 | 6. (4 points) Consider the program below, using the qualified types annotations for tainted flows given in the lecture (shown in comments). In particular, notice that the variable fmt and the argument to printf are untainted, while the result of fgets is tainted. Suppose we analyze this with a tainted flow analysis. This program has no bugs, but which kinds of analysis report a false alarm? 51 | 52 | /* int printf(untainted char *fstr, ...); */ 53 | /* tainted char *fgets(...); */ 54 | char *chomp(char *s) { 55 | int i, len = strlen(s); 56 | for (i = 0; i 5) { 143 | if (y > 7) { 144 | printf("here\n"); 145 | } else { 146 | if (x < 20) 147 | printf("everywhere\n"); 148 | else 149 | printf("nowhere\n"); 150 | } 151 | } 152 | } 153 | 154 | ¬(y > 7) ∧ x < 20 155 | 156 | x > 5 ∧ ¬(y > 7) ∧ ¬(x < 20) 157 | 158 | x > 5 ∧ ¬(y > 7) ∧ x < 20 159 | 160 | x > 5 ∧ y > 7 ∧ x < 20 161 | 162 | 13. Suppose that x in the following program is symbolic. When the symbolic executor reaches the line that prints "here" what will the path condition be? 163 | 164 | void bar(int x) { 165 | int z; 166 | if (x > 5) 167 | z = 5; 168 | else 169 | z = 1; 170 | if (z > 3) 171 | printf("here\n"); 172 | } 173 | 174 | x > 5 ∧ z > 3 175 | 176 | x > 5 177 | 178 | ¬(x > 5) ∧ z > 3 179 | 180 | z > 3 181 | 182 | 14. Which of the following are heuristics that symbolic executors use to cover more of the search space? 183 | 184 | Switch between concolic and non-concolic execution 185 | 186 | Choose between two paths based on a notion of priority 187 | 188 | Choose between two paths based on whether one reaches program statements not previously executed 189 | 190 | 191 | -------------------------------------------------------------------------------- /w6/1_pen-testing-intro.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w6/1_pen-testing-intro.pdf -------------------------------------------------------------------------------- /w6/2_pen-testing.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w6/2_pen-testing.pdf -------------------------------------------------------------------------------- /w6/3_fuzzing.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ramizebian/Software-Security/1be56db216c2627b70aff400136b56c680dc531a/w6/3_fuzzing.pdf -------------------------------------------------------------------------------- /w6/week-6-quiz: -------------------------------------------------------------------------------- 1 | Week 6 quiz 2 | 3 | 1. What is penetration testing? 4 | 5 | A procedure for testing libraries or other program components for vulnerabilities 6 | 7 | All of the above 8 | 9 | Whole-system testing for security flaws and bugs 10 | 11 | A security-minded form of unit testing that applies early in the development process 12 | 13 | 2. Which of the following are benefits of penetration testing? 14 | 15 | You can prove a positive: Penetration testing will establish your system is secure 16 | 17 | Compositionality of security properties means tested components are secure even if others change 18 | 19 | They specifically consider adversarial thinking, which is not usually necessary for normal tests 20 | 21 | Results are often reproducible 22 | 23 | 3. What does it mean to "be stealthy" during a penetration test? 24 | 25 | Performing the tests from an undisclosed location 26 | 27 | Taking care to avoid activities during a penetration test that might attract attention, e.g., by operators or IDS services 28 | 29 | Using encryption during tests to make the source of attacks impossible to determine 30 | 31 | Performing penetration testing without the target organization knowing 32 | 33 | 4. What is a web proxy? 34 | 35 | A piece of software that intercepts and possibly modifies requests (and responses) between a web browser and web server 36 | 37 | An agent that makes decisions on the client's behalf when interacting with web applications 38 | 39 | A piece of software that makes a web application look like a standalone application, making it easier to test 40 | 41 | A simulator for the web, for use when off-line 42 | 43 | 5. What is Nmap? 44 | 45 | It is a scanner which works by injecting packets to a range of addresses, and inferring what hosts and services might be at those addresses, based on the responses 46 | 47 | It is a map of the Internet 48 | 49 | It is a network fuzz testing tool 50 | 51 | It is a suite of tools for scripting attacks: probe, construct, encode, inject, wait for response 52 | 53 | 6. What is ethical hacking? 54 | 55 | Hacking into systems run by those whose ethics you disagree with 56 | 57 | "Hacking" ethics so they justify unintended selfish behavior 58 | 59 | Hacking systems (e.g., during penetration testing) to expose vulnerabilities so they can be fixed, rather than exploited 60 | 61 | A slang term for rapid software development, e.g., as part of hackathons 62 | 63 | 7. Which of the following statements describe fuzz testing (aka fuzzing)? 64 | 65 | It is concerned with finding known-bad behaviors, like crashes and hangs 66 | 67 | It focuses on simple testing patterns and does not employ sophisticated analysis techniques 68 | 69 | It is always black-box, in being indifferent to the software's functionality 70 | 71 | It has been used to find security vulnerabilities in many commodity programs 72 | 73 | 8. Which of the following are true of whitebox fuzzing? 74 | 75 | It takes into account the program's internals in some manner when deciding which inputs to choose 76 | 77 | Radamsa is (at least in part) a whitebox fuzzer 78 | 79 | SAGE is (at least in part) a whitebox fuzzer 80 | 81 | It makes no sense to combine it with grammar-based fuzzing since the latter is just another way to consider the program's semantics 82 | 83 | 9. Which of the following is true of mutation-based fuzzing? 84 | 85 | It only makes sense for file-based fuzzing, not network-based fuzzing 86 | 87 | Each input is mutation that follows a given grammar 88 | 89 | It works by making small mutations to the target program to induce faults 90 | 91 | It generates each different input by modifying a prior input 92 | 93 | 10. Which of the following styles of fuzzer is more likely to explore paths covering every line of code in the following program? 94 | 95 | Blackbox 96 | 97 | Whitebox 98 | 99 | Mutation-based 100 | 101 | Generational 102 | 103 | 11. Which of the following are functions of a network-based fuzzer? 104 | 105 | Scanning a network address range 106 | 107 | Acting as a "man in the middle" 108 | 109 | Acting as a server 110 | 111 | 12. Suppose you want to use fuzzing on a program to try to find memory errors; which of the following statements is true? 112 | 113 | Fuzzing doesn't find memory errors, it finds crashes and hangs 114 | 115 | You should not use a grammar-based fuzzer, because its adherence to the grammar means it will not find memory errors 116 | 117 | Compiling the program with address sanitizer (ASAN) will make errors harder to reproduce 118 | 119 | Compiling the program with address sanitizer (ASAN) will make the source of a memory error easier to find 120 | 121 | --------------------------------------------------------------------------------