The editorial team at ProProfs Quizzes consists of a select group of subject experts, trivia writers, and quiz masters who have authored over 10,000 quizzes taken by more than 100 million users. This team includes our in-house seasoned quiz moderators and subject matter experts. Our editorial experts, spread across the world, are rigorously trained using our comprehensive guidelines to ensure that you receive the highest quality quizzes.
Do you think you know enough about security issues in C code? Can you think with the mind of a hacker? Test your knowledge with our interactive quiz! Check how much you know, share the results, and help your colleagues learn more about secure coding. Simply click on the "start" button. It's fun and easy - so don't wait!
Questions and Answers
1.
This function is part of a program that is running on a 32-bit x86 system; the compiler does not change the order of variables on the stack.
void function(char *input)
{
int i = 1;
char buffer[8];
int j = 2;
strcpy(buffer,input);
printf("%x %x %s\n",i,j,buffer);
}
What is the minimum length of a string – passed to the function through the input parameter – that can crash the application?
A.
9
B.
10
C.
11
D.
12
E.
13
Correct Answer
D. 12
Explanation 12 characters. Since the string is zero-terminated, it will be stored in a 13-byte array that is copied over the buffer, and the first byte of the EBP will be overwritten - causing the program to crash.
Rate this question:
2.
The program below is running on a 32-bit x86 system and the compiler does not change the order of variables on the stack.
If the memory address of puts("Access granted") is 0x004010B6, what does the input need to be in order to force the program into accepting an invalid password? (answers are in hex string format)
#include <stdio.h>
#include <string.h>
void function(char *input)
{
int i = 1;
char buffer[8];
int j = 2;
strcpy(buffer,input);
printf("%x %x %s\n",i,j,buffer);
}
int main(int argc, char* argv[])
{
int k=3;
function(argv[1]);
if (strcmp(argv[1],"secret")) {
puts("Access denied");
return -1;
}
else {
puts("Access granted");
}
return 0;
}
A.
00000000000000000000000000000000b6104000
B.
00000000000000000000000000000000004010b6
C.
20202020202020202020202020202020004010b6
D.
2020202020202020202020202020202020b61040
E.
20202020202020202020202020202020b6104000
Correct Answer
E. 20202020202020202020202020202020b6104000
Explanation From this string, the 0-7 bytes are placed in the buffer variable, the 8-11 bytes overwrite the "i" variable, the 12-15 bytes overwrite the stack base pointer [EBP], and the 16-19 bytes overwrite the return address. Since the x86 architecture is little-endian, the memory address needs to be stored as b6104000. As we're using strcpy, the string should not have any NUL characters in it, except for the trailing zero.
Rate this question:
3.
void function()
{
int i,j,k;
unsigned int u,v;
i = INT_MAX; // 2147483647
i++;
printf("i = %d, ", i);
j = INT_MIN; // -2147483648
j--;
printf("j = %d, ", j);
k = INT_MIN; // -2147483648
k = abs(k);
printf("k = %d, ", k);
u = UINT_MAX; // 4294967295
u++;
printf("u = %u, ", u);
v = 0;
v--;
printf("v = %u", v);
}
Which of the following strings will be written to stdout?
A.
I = 2147483648, j = -2147483649, k = 2147483648, u = 4294967296, v = -1
B.
I = -2147483648, j = 2147483647, k = 2147483648, u = 0, v = 4294967295
C.
I = 0, j = 0, k = 2147483648, u = 0, v = 4294967295
D.
I = -2147483648, j = 2147483647, k = -2147483648, u = 0, v = 4294967295
E.
I = -2147483648, j = 2147483647, k = 0, u = 0, v = 4294967295
Correct Answer
D. I = -2147483648, j = 2147483647, k = -2147483648, u = 0, v = 4294967295
Explanation Due to the 2’s complement calculation, the value of i will overflow into INT_MIN and the value of j will overflow into INT_MAX. The abs() function calculates the result by multiplying the input with -1 if it is negative; since 2147483648 cannot be represented in a 32-bit signed integer, k will overflow into INT_MIN. u will overflow to 0 since UINT_MAX+1 cannot be represented in a 32-bit unsigned integer. Similarly, v will overflow to UINT_MAX.)
Rate this question:
4.
Which of the following is true with respect to buffer overflows?
A.
Buffer overflows on the heap cannot be exploited to run arbitrary code.
B.
If a function is vulnerable to a buffer overflow due to large user input being put in a small fixed-size buffer, making the buffer 10 times as large as a “quick fix” will reduce the impact of the vulnerability.
C.
Buffer overflows can be used to alter the state and operation of the vulnerable application in an undetectable way.
D.
If code cannot be executed on the stack (e.g. through the use of the non-execute bit or DEP), attackers cannot run arbitrary code by exploiting a buffer overflow.
E.
Calling free() on the same memory address twice may crash the application, but will not lead to an exploitable buffer overflow.
Correct Answer
C. Buffer overflows can be used to alter the state and operation of the vulnerable application in an undetectable way.
Explanation a]NO; heap-based buffer overflows are significantly harder to exploit, but they can still be used to run arbitrary code.
b]NO; in most cases, the attacker can put extremely long input – several hundred kilobytes of data, or even more – in the fixed-size buffer. Increasing the buffer size will only allow the attacker to inject longer shellcode in most cases.
c]YES; e.g. if the attacker only overwrites local variables on the stack.
d]NO; there are several techniques to avoid DEP and similar techniques, such as return-to-libc attacks and return-oriented programming.
e]NO; in the right circumstances, a double free can lead to a buffer overflow on the heap.
Rate this question:
5.
What would you substitute for A and B to ensure that the function will work properly for any data1 and data2 value?
const unsigned short int MAX_BUFFER_SIZE=4096;
char *mergeData(char * data1, char * data2) {
char *buffer=null;
unsigned int d1len = strlen(data1);
unsigned int d2len = strlen(data2);
if(A) {
buffer = (char *) malloc(B);
if(buffer)
sprintf_s(buffer, B, "%s,%s", data1, data2);
}
return buffer;
}
A.
A: d1len + d2len
B.
A: d1len
C.
A: (d2len + 2
D.
A: d1len + d2len + 2
E.
A: (d2len
Correct Answer
E. A: (d2len
Explanation It is necessary to allocate strlen(data1)+strlen(data2)+2 bytes because there is a comma between the two strings in the sprint and the trailing zero needs to be stored as well. However for very large d1len and small d2len values or vice versa – e.g. if the data1 string is 65534 bytes long and data2 is 1 byte long – d1len+d2len+2 could overflow to a number which is less than MAX_BUFFER_SIZE and pass the validation. Therefore, the input validation itself needs to avoid arithmetical integer overflows – in this case, this is accomplished by doing two separate checks that are each immune to overflow.
Rate this question:
6.
Which value for the toprint parameter causes the function to print out the secret password in the code below?
#define INPUT_SIZE 16
bool checkPass(char *toprint)
{
bool result;
char input[INPUT_SIZE]="";
char *secret;
secret=(char*)malloc(INPUT_SIZE);
Readfile("SecretPassword.txt",secret,INPUT_SIZE);
printf(toprint);
gets_s(input,INPUT_SIZE);
result=!strcmp(secret,input);
free(secret);
return result;
}
A.
%n %08x %08x %08x %08x %08x
B.
%08x %08x %08x %08x %08x %s
C.
%s %08x %08x %08x %08x %08x
D.
%100s
E.
%08x %08x %08x %08x %08x %08x
Correct Answer
B. %08x %08x %08x %08x %08x %s
Explanation The correct solution is b. The four '%08x's get the printf to read past the unimportant local variables ('result': 4-byte boolean, 'input': 16-byte array), and the '%s' will process the secret char pointer as a string and print out its contents.
Rate this question:
7.
If, in the code below, toprint points to the '%08x %08x %08x %08x %08x %n' string, what character does the user have to enter in order to pass the password verification regardless of the password value read from SecretPassword.txt?
#define INPUT_SIZE 16
bool checkPass(char *toprint)
{
bool result;
char input[INPUT_SIZE]="";
char *secret;
secret=(char*)malloc(INPUT_SIZE);
Readfile("SecretPassword.txt",secret,INPUT_SIZE);
printf(toprint);
gets_s(input,INPUT_SIZE);
result=!strcmp(secret,input);
free(secret);
return result;
}
A.
0x08
B.
0x0A
C.
0x15
D.
0x28
E.
0x2D
Correct Answer
E. 0x2D
Explanation %n writes the number of bytes that have been written out so far into the string the stack pointer is currently pointing at. In this case there were 20 bytes read off the top of the stack (the 'result' and 'input' variables) and 45 characters written out ('%08x' writes 8 characters, and there are 6 spaces). So the 0x2D (45 in hex) will be stored in the memory area referenced by the 'secret' pointer.
Rate this question:
8.
Which of the following statements (in the area of protection against typical C/C++ vulnerabilities) is true?
A.
There is no reliable way to protect against format string vulnerabilities.
B.
Injected shellcode can be reliably identified by intrusion detection software.
C.
Proper use of secure integer libraries eliminates integer overflow vulnerabilities.
D.
Using data execution prevention, address space layout randomization and stack smashing protection at the same time provides complete protection against buffer overflow exploits.
E.
Using strncpy and strncat instead of strcpy and strcat guarantees error-free operation.
Correct Answer
C. Proper use of secure integer libraries eliminates integer overflow vulnerabilities.
Explanation a] NO; format string vulnerabilities are trivially avoided by e.g. #define printf(str) printf("%s",str)
b] NO; shellcode can be obfuscated, encrypted, or even masquerade as alphanumeric text.
c] YES; secure integer libraries either prevent overflows altogether or throw errors when an overflow is encountered.
d] NO; heap spraying, return-oriented programming, return-to-libc and similar techniques can be used to bypass these protections.
e] NO; strncpy/strncat do not add a trailing zero if the 'num' parameter specifying the number of characters to copy is greater than the length of source string. This can lead to a buffer overflow later when the string is read out.
Rate this question:
9.
When dealing with Unicode user input in C, the following issues need to be taken into account:
A.
Unicode characters may be used to bypass black-list filtering
B.
In every encoding form, the size of Unicode characters may differ from each other
C.
The length() of a Unicode string may be different from its size()
D.
Unicode strings cannot be printed easily out on the screen
E.
Directional control characters such as U+202E may be exploited
Correct Answer(s)
A. Unicode characters may be used to bypass black-list filtering B. In every encoding form, the size of Unicode characters may differ from each other C. The length() of a Unicode string may be different from its size() E. Directional control characters such as U+202E may be exploited
Explanation a]YES; filtering may use a different Unicode conversation routine than the called function.
b]YES; the character representation length varies for different characters in UTF-8 encoding form.
c]YES; depending on the Unicode encoding being used, size may be up to 4x larger than length.
d]NO; every function has an Unicode pair, for example you can use wprintf instead of printf.
e]YES; if the user-provided string is concatenated with UI elements, it may be used to reverse built-in UI element text.
Rate this question:
10.
#define ll 12
char pwd[37], n[ll];
void s(char *u) {strncpy(n,u,ll); printf(n);}
How would you fix the code above?
Correct Answer(s)
D. Void s(char *u) {strncpy(n,u,11); printf(“%s”, n);} E. Void s(char *u) {strncpy(n,u,ll-1); cout
Explanation a]NO; this fixes the off-by-one error in the strncpy, but does not fix the printf vulnerability
b]NO; neither of the bugs is fixed in this way, just increases the string’s size by one
c]NO; this fixes the off-by-one error in the strncpy, but does not fix the printf vulnerability
d]YES; both the off-by-one error and the printf vulnerability are fixed, but hard-coding the number of characters to be copied may cause problems in the future
e]YES; both the off-by-one error and the printf vulnerability are fixed
Rate this question:
Quiz Review Timeline +
Our quizzes are rigorously reviewed, monitored and continuously updated by our expert board to maintain accuracy, relevance, and timeliness.