Closed mustakimur closed 3 years ago
Professor, I looked over all the code in parseTree.cpp (as well as the other files) and could not find a clear reason for why j could be causing the invalid memory access. The only possible thing that I thought of could be the following:
when the variable i is initialized, it is set as i=start. When j is initialized, it is done by using i ( int j = i + 3) and the same thing for the variable openBracNum (int openBracNum = i + 1). Both the variables are initialized by using the value of i, so the issue may possibly be with the initialization of i.
What are your thoughts on this?
@ellezeeman why not you print out the value start
for the exploit input and see if that is a negative value? and if you can reopen the issue, please do so until the problem is fixed.
Here is a code (from parseTree.cpp) that I have modified with debug information.
// cout << "I" << endl;
cout << "[DEBUG] Value i initilizes openBracNum: " << i << endl;
if (tokens[i + 1] == "(")
{
string fnName = tokens[i];
//cout << "II here" << endl;
int openBracNum = i + 1;
//cout << "tokens[openBracNum]: " << tokens[openBracNum] << endl;
/*cout << "\nParenthesis map : \n";
unordered_map<int, int>::iterator itr;
for (itr = parenthesisMap.begin(); itr != parenthesisMap.end(); itr++)
{
cout << itr->first << " " << itr->second << endl;
}
cout << "--------------" << endl;*/
auto it = parenthesisMap.find(openBracNum);
//cout << "III here: " << it -> second << endl;
int closeBracNum = it->second;
//cout << "IV here" << endl;
cout << indent << " call fn " << tokens[i] << endl;
indent.append("-");
cout << "[DEBUG] openBracNum initializes value j: " << openBracNum << endl;
for (int j = openBracNum + 1; j < closeBracNum; j++)
{
cout << "[DEBUG] My first debug (token size vs j): " << tokens.size() << " compare to " << j << endl;
if (tokens[j] != ",")
{
if (tokens[j] == "\"")
{
int closeQuotes;
cout << "[DEBUG] closeQuotes uninitialized value: " << closeQuotes << endl;
string stringVal = "\"";
for (int k = j + 1; k < end; k++)
{
stringVal.append(tokens[k]);
if (tokens[k] == "\"")
{
cout << "[DEBUG] closeQuotes assing with value k: " << k << endl;
closeQuotes = k;
break;
}
}
cout << indent << " arg "
<< " string " << stringVal << endl;
cout << "[DEBUG] closeQuotes modifies j with +1: " << closeQuotes << endl;
j = closeQuotes + 1;
i = j;
}
else
{
//cout << "V, j: " << j << " tokens[j]: " << tokens[j] << endl;
/*cout << "\nAll Elements : \n";
unordered_map<string, string>::iterator itr;
for (itr = newVarTypeMap.begin(); itr != newVarTypeMap.end(); itr++)
{
cout << itr->first << " " << itr->second << endl;
}
cout << "--------------" << endl;*/
string key;
//cout << "fnNAme: " << fnName << endl;
if (fnName == "scanf")
{
// cout << "I-" << endl;
if(tokens[j].substr(0,1)=="&"){
key = tokens[j].substr(1);
// cout << "II-" << endl;
}
}
else
{
//cout << "II" << endl;
key = tokens[j];
}
// cout << "key: " << key << endl;
auto it1 = newVarTypeMap.find(key);
//cout << "VI" << endl;
//cout << it1->second << endl;
if(it1 != newVarTypeMap.end()){
string type = it1->second;
//cout << "VII" << endl;
cout << indent << " arg " << type << " " << key << endl;
}
}
}
}
indent.pop_back();
}
}
The output for exploitable input is:
function print
- return int
- param int in
- param st msg
-- if in lt 0
[DEBUG] Value i initilizes openBracNum: 19
--- call fn strcpy
[DEBUG] openBracNum initializes value j: 20
[DEBUG] My first debug (token size vs j): 131 compare to 21
---- arg st msg
[DEBUG] My first debug (token size vs j): 131 compare to 22
[DEBUG] My first debug (token size vs j): 131 compare to 23
[DEBUG] My first debug (token size vs j): 131 compare to 24
[DEBUG] My first debug (token size vs j): 131 compare to 25
[DEBUG] My first debug (token size vs j): 131 compare to 26
[DEBUG] My first debug (token size vs j): 131 compare to 27
[DEBUG] My first debug (token size vs j): 131 compare to 28
[DEBUG] My first debug (token size vs j): 131 compare to 29
[DEBUG] closeQuotes uninitialized value: -33
---- arg string ");EndOfLine
[DEBUG] closeQuotes modifies j with +1: -33
[DEBUG] My first debug (token size vs j): 131 compare to -31
Segmentation fault
Let's see if you can now find out the original problem.
The following vulnerability is detected by AFL Fuzzer.
The following input cause a crash to the program:
The debug shows vulnerable code location:
The source code location shows an invalid memory(tokens[j]) access with invalid indexing (j):
Further debug of following code results:
output:
A negative index value is received. Definitely, the origin of problem is further back.
Invalid memory access is a classic example of causing control flow hijack. The invalid memory can hold malicious code and cause further damange.