N-Prolog is a Prolog interpreter, mainly used for experimenting with logic programming and artificial intelligence algorithms. In October 2022, security researchers discovered a serious buffer overflow vulnerability (CVE-2022-43343) in N-Prolog version 1.91, specifically in the gettoken() function located in Main.c. This bug has serious implications because it can potentially allow arbitrary code execution.

This post will explain what the bug is, where it is found, why it matters, and how it can be exploited, with simple examples and code snippets.

What is a Buffer Overflow?

A buffer overflow happens when a program writes more data to a buffer (an array or block of memory) than it can hold. This can lead to adjacent memory locations—sometimes including critical data or control flow structures—being overwritten. In the worst case, a skilled attacker might use this to execute their own code.

Overview of N-Prolog v1.91 and gettoken()

N-Prolog is written in C, and gettoken() is responsible for reading tokens from input. It uses a local buffer of fixed size to store user input or parts of it.

If the program does not correctly check if the user input is too big for the buffer, a buffer overflow will result.

Where Exactly Is the Vulnerability?

The vulnerability is in Main.c in the gettoken() function, around how it handles input and writes to a buffer. It does not correctly ensure that the buffer will not overflow when new data is added.

A simplified and illustrative example of unsafe code

char buffer[256];
int i = ;
int ch;
while ((ch = getchar()) != EOF && ch != '\n') {
    buffer[i++] = ch; // <-- No boundary check!
}
// ...

The code adds input characters to buffer, increasing i each time. There’s NO check to make sure i stays less than 256. If the user gives a long string, i can go beyond 255, and the code writes after the end of buffer. This causes a global buffer overflow.

Actual Vulnerable Code Snippet

Here is a snippet close to what was discovered in the vulnerable N-Prolog code (source):

char symbuf[MAXTOKEN]; // Assume MAXTOKEN is 256
int symindex = ;
int ch;

while ((ch = getc(infile)) != EOF && !isspace(ch)) {
    symbuf[symindex++] = ch;
}

There is no check that symindex stays inside the bounds of symbuf. An attacker who can control the input can write past the buffer’s boundaries.

How Can This Be Exploited?

Buffer overflows are one of the top ways attackers get code execution on C programs.

1. Via Crafted Input

An attacker supplies overly long input—200 or more bytes—which overflows the buffer. The overwritten data on the stack or global memory could include:

Other critical variables

If the attacker sets the data just right, when the code later executes or returns, it could jump to the attacker's code, which could do anything (perhaps spawn a shell).

A simple exploit is just to crash the interpreter—for instance, as a Proof of Concept (PoC)

python3 -c "print('A'*1024)" | ./nprolog

Launching nprolog (the binary for N-Prolog v1.91) with a long string causes a crash, often with a segmentation fault.

Responsible Disclosure and Fix Status

As of the time of writing (early 2024), the official repository for N-Prolog has not published a fix for this vulnerability.

References

- Official Github Repo
- CVE Details Entry
- Full Patch/Disclosure by Cyber Security Works

How to Fix?

The fix is simple: always check that buffer indexes stay inside their bounds.

A safe snippet

if (symindex < MAXTOKEN)
    symbuf[symindex++] = ch;
else
    // handle error, maybe break or discard further input

Or use safer C alternatives like fgets() or strncpy() when possible.

Recommendations

1. Users: Until patched, avoid using N-Prolog v1.91 on sensitive systems. Only process trusted input.

Developers: Patch your code as above. Always do bounds checking.

3. Defenders: Consider monitoring for abnormal crashes of N-Prolog and do not allow it to parse untrusted data.

Conclusion

CVE-2022-43343 in N-Prolog v1.91 is a classic buffer overflow issue that could allow arbitrary code execution if triggered properly. Even though N-Prolog is not as popular as other interpreters, this is another reminder of why careful programming in C is necessary, and why old code should be reviewed for security bugs.

Further Reading

- Buffer Overflows: The Basics
- Smashing the Stack for Fun and Profit (classic paper)
- CVE-2022-43343 at NIST


If you want to discuss secure programming in C or other topics, leave a comment or get in touch!

Timeline

Published on: 11/08/2022 15:15:00 UTC
Last modified on: 11/08/2022 19:26:00 UTC