Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2019-25485 — Stack-based buffer overflow in R 3.4.4. Full exploitation on x86, but only RIP control with gadget analysis on x64 due to program constraints. The same vulnerability across two architectures, leading to different exploitation paths. | Kitploit
Tools/GitHubGitHub/themalwareguardian/cve-2019-25485
Vulnerability AnalysisExploitationReverse EngineeringShellcodeDebuggersLearning & EducationPayload DevelopmentBinary Exploitation
GitHub
themalwareguardian/cve-2019-25485

CVE-2019-25485

Stack-based buffer overflow in R 3.4.4. Full exploitation on x86, but only RIP control with gadget analysis on x64 due to program constraints. The same vulnerability across two architectures, leading to different exploitation paths.

View Repository
35 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

🐞 CVE-2019-25485: R 3.4.4 - Stack-Based Buffer Overflow (x86 and x64)

Stack-based buffer overflow in R 3.4.4. Full exploitation on x86, but only RIP control with gadget analysis on x64 due to program constraints. The same vulnerability across two architectures, leading to different exploitation paths.




📑 Table of Contents

  • Why this repository exists
  • Why this vulnerability is interesting
  • Context and affected software
  • About the vulnerability
  • Triggering the crash
  • Exploitation



🎓 Why this repository exists

This repository is part of the material I use when teaching memory corruption exploitation (in addition to my regular work, I also teach in different cybersecurity courses where I help train the next generation of reverse engineers).

CVE-2019-25485 is the case I use when I want students to work through the same vulnerability on two different architectures and see firsthand what changes between them. R 3.4.4 ships in both x86 and x64 versions, and the exact same overflow exists in both, the same GUI field, the same input handler, the same crash. Both are documented and exploited here as separate exercises:

  • The x86 version follows the classic vanilla EIP overwrite methodology. The overflow reaches EIP, a JMP ESP gadget is found in a module without ASLR, shellcode is placed after the EIP overwrite, and a working reverse shell is achieved. It is a clean and direct exploit that demonstrates the fundamentals of stack-based buffer overflows.
  • The x64 version reaches RIP control and confirms the offset, but full RCE is not achieved. This is deliberate and is the point of the exercise. The x64 exploitation attempt documents the gadget search process in full, analyzes why each gadget category fails in this specific context, explains the null byte constraint imposed by the input handler, and describes the ROP chain structure that would be needed to bypass DEP and why it cannot be built given the constraints of this input vector. The only remaining theoretical path to full exploitation from this single vulnerability would be JOP, Jump-Oriented Programming, which chains gadgets ending in JMP rather than RET and does not rely on the stack for control flow. Constructing a JOP chain manually without any writable controlled region after the RIP overwrite is an advanced open challenge that goes beyond the scope of this exercise. The failure is not a gap in the methodology. It is the lesson.



💡 Why this vulnerability is interesting

R 3.4.4 is a statistical computing application, not a network service or a browser. The overflow is triggered through a desktop GUI field, which means the attack surface is completely different from every other case I teach. What makes this case useful for teaching:

  • No network component. The payload is pasted into a GUI field, which introduces a different class of constraints, in particular how the GUI input handler processes bytes before they reach the vulnerable copy operation.
  • RIP control is confirmed. The overflow reaches RIP and the offset is found. This is not a case where the vulnerability cannot be reached. Control of the instruction pointer is fully demonstrated.
  • Canonical address enforcement breaks the classic approach. On x86 you overwrite EIP and append shellcode. On x64 the upper bytes of RIP must be \x00\x00 for the address to be canonical, and those null bytes terminate the input immediately after the gadget address. There is no space for shellcode or ROP chain values after the overwrite.
  • Null byte conversion blocks ROP. The GUI field converts null bytes to spaces before copying to the buffer. Every x64 address contains null bytes in the upper half. No gadget address can be placed on the stack as a ROP chain value, they all arrive corrupted.
  • DEP blocks direct execution. Even if a way to reach the shellcode buffer were found, DEP is enforced and blocks execution on the stack.
  • Gadget searching is documented in full. The process of dumping gadgets from every loaded module, filtering by type, and reasoning about why each gadget fails is documented step by step. This is the core skill that every exploit developer needs.
  • The ROP chain skeleton for VirtualProtect is explained. Students see exactly what would be needed to bypass DEP, why the calling convention matters, and why this specific chain cannot be built given the input constraints.



🔍 Context and affected software

R is a statistical computing and graphics environment available for Windows, macOS, and Linux. The vulnerability is in the GUI Preferences dialog, specifically the Language for menus and messages field, which copies user input into a fixed-size stack buffer without validating its length.

Key technical details:

  • Vulnerability type: Stack-based buffer overflow
  • Affected version: R 3.4.4 x86_x64
  • Affected endpoint: Edit -> GUI Preferences -> Language for menus and messages
  • Vulnerable component: GUI preferences input handler
  • Authentication required: No (local application)
  • Impact: x86 - Remote code execution | x64 - Control flow confirmed



⚠️ About the vulnerability

R 3.4.4 processes the Language for menus and messages field by copying the supplied string into a fixed-size stack buffer without checking its length. A simplified version of the vulnerable logic looks like this:

root@kitploit:~
char language_buffer[256];

strcpy(language_buffer, user_input);

Sending a sufficiently long string causes the copy to write past the end of the buffer, corrupting the stack until the saved return address is overwritten. When the function returns, the CPU loads the attacker-controlled value from the stack into RIP and attempts to jump to it.

On x64, Windows enforces canonical address validation before any jump takes place. A non-canonical value like 0x4141414141414141 triggers an immediate access violation before RIP is loaded, which means the crash looks different from x86, no clean RIP = 4141414141414141. The offset must be found by reading the cyclic pattern from the stack after the crash rather than from RIP directly.




💥 Triggering the crash

The crash can be reproduced by pasting a long string into the language field. No authentication is required. Example using Python to generate the payload:

root@kitploit:~
import struct

payload = b'A' * 400

with open('payload.txt', 'wb') as f:
	f.write(payload)
root@kitploit:~
Open R 3.4.4 x64
Edit -> GUI Preferences
Paste contents of payload.txt into Language for menus and messages
Click OK
Download Tool



💣 Exploitation

The goal of this repository is not only to demonstrate the crash, but to walk through the complete exploitation process on both architectures, documenting what works on x86, what breaks on x64, and more importantly, why.

To keep the main README clean, the detailed exploitation notes, scripts, and debugger steps are placed inside the Vulnerability 📂 folder of this repository, organized into separate x86 and x64 subfolders.

There you will find the complete workflow for both architectures:

x86 - Full exploitation:

  • Fuzzing the language field to identify the crash.
  • Offset discovery to locate the exact position of EIP on the stack.
  • Bad character analysis to identify bytes that corrupt the payload.
  • Locating a JMP ESP gadget in stats.dll, a module compiled without ASLR or SafeSEH.
  • Shellcode placement and execution, full reverse shell achieved.

x64 - RIP control and exploitation analysis:

  • Configuring x64dbg to avoid constant interruptions from DLL load events.
  • Fuzzing the language field across three phases to find the exact crash size.
  • Finding the RIP offset by reading the cyclic pattern from the stack rather than from RIP.
  • Confirming RIP control using a 6-byte overwrite with automatic null byte padding.
  • Identifying the null byte to space conversion as the fundamental input constraint.
  • Dumping gadgets from all loaded R modules using rp++ and filtering with PowerShell.
  • Analyzing each gadget category, CALL RBX, CALL RSP, POP RSP, SUB RSP, PUSH RSP, and documenting why each one fails in this specific context.
  • Explaining the ROP chain structure required to call VirtualProtect and bypass DEP, and why it cannot be built given the null byte constraint.
  • Documenting JOP as the only remaining theoretical path and why it remains an open challenge.