Easy Grade Pro 4.1 file parsing bug used as an educational example to show how beginners can start vulnerability research through reverse engineering.
An educational example created to show beginners that vulnerability research through reverse engineering is possible from the very start.
This repository comes from the need to have a simple example that could be used when teaching beginners who are starting in vulnerability research, especially those who are interested in reverse engineering.
After completing a course, a training session, or a master program related to binary exploitation or binary analysis, many students feel that real vulnerability research is something far beyond their level. They usually associate reverse engineering with very advanced topics such as kernel vulnerabilities, browser exploitation, firmware research, or complex modern targets, and because of that, they think they are not ready yet. In practice, the problem is not the lack of knowledge, but the lack of a realistic starting point.
I wanted an example that could show that with the skills learned during a basic course, it is already possible to take a real program, understand how it works, trigger a crash, and identify a real bug.
This repository is exactly that kind of example. It is not about finding a complex vulnerability. It is about showing that beginners can start from something small, reproducible, and understandable, and still be doing real vulnerability research.
This repository is directly related to my talk "The Path That Leads to Your First CVE", where I explain that there are multiple ways to enter the world of vulnerability research, and that each person usually ends up following a different path depending on their interests.
Some people start with source code auditing, others with reverse engineering, others with web security, and others with technology research. All of these paths are valid, but the important part is understanding that every area also has beginner-friendly entry points.
Examples of beginner paths include:
These kinds of targets may look basic, but they teach the same core skills that are needed later when working on complex systems.
This repository represents one of those beginner paths in the reverse engineering field.
The vulnerability documented here was found by analyzing an old application, understanding how its file format is parsed, and identifying a programming mistake that leads to a crash. The impact itself is not complex, but the process is real, reproducible, and useful for learning how vulnerability research actually works.
This is the type of example I use when explaining "The Path That Leads to Your First CVE", to show that reverse engineering is a valid path from the very beginning, and that starting with simple targets is not only acceptable, but often the best way to learn.
When you are starting, modern applications are often too complex. They use protections, mitigations, and codebases that are difficult to understand without a lot of experience. Old software is different.
Legacy applications were not written with modern security practices in mind. They often contain simple parsing bugs, unsafe memory operations, and logic errors that can be understood with basic reversing skills. That makes them perfect for learning.
With an old program you can: reverse the binary, understand the file format, trigger a crash, analyze the crash, locate the bug, document the issue, and report the vulnerability. In other words, you learn the fundamental skills that every vulnerability researcher needs.
That is exactly what this example is about.
This example is important because it shows something very simple:
If you like reverse engineering, you can follow that path from the beginning. It may take years to master it, but you do not need to wait years to start doing real work.
The vulnerability (CVE-2025-70330)) affects the file parsing logic of Easy Grade Pro 4.1 when loading proprietary .EGP gradebook files.
The application reconstructs internal gradebook structures by reading fixed-position fields from the file and using those values as offsets inside the loaded file buffer. These offsets are later used to calculate memory sizes and to copy data into dynamically allocated buffers.
Under normal conditions, the file passes several structural checks before the parsing continues. However, once these checks succeed, the parser trusts the offset values stored inside the file without validating that they remain within the bounds of the loaded buffer.
By modifying specific bytes inside an otherwise valid .EGP file, it is possible to corrupt these internal offset calculations. When the parser later uses these values, it attempts to read memory outside the valid file region, which results in an access violation and application crash.
This condition corresponds to an out-of-bounds read (CWE-125), leading to a local denial-of-service when the crafted file is opened.
The .EGP file format is parsed using an offset-based approach. Instead of processing the file sequentially, the parser reads internal structures that contain start and end offsets describing where specific data blocks should be located inside the file.
These offsets are used to calculate the size of a memory region and to copy data from the loaded file buffer into newly allocated memory.
The vulnerable logic can be summarized as:
size = offset_end - offset_start + 1
buffer = calloc(1, size)
memcpy(buffer, file_buffer[offset_start - base_offset], size)
Once the file passes the initial validation checks, the parser assumes that the offsets stored in the file are valid. No verification is performed to ensure that the computed source pointer remains inside the loaded file buffer.