Skip to content

Instantly share code, notes, and snippets.

@Aptimex
Last active January 9, 2020 21:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Aptimex/55a5540245b7e16f64b4147feebcf399 to your computer and use it in GitHub Desktop.
Save Aptimex/55a5540245b7e16f64b4147feebcf399 to your computer and use it in GitHub Desktop.
Codebreaker 2018 notes

Codebreaker 2018 notes

These notes are just a markdown-formatted version of my actual working notes from this challenge. This is not designed to be a walkthrough, it's just an archive of my thought process for future reference.

Task 0:

Only two IPs in the packet capture, and we are told what our victim IP is, so...
Attacker (LP) IP = 172.25.169.92

Task 1:

Network analysis notes

Packet 4 (target -> LP): [must have Encrypted Ransom Key and OTP value (ASCII?)] 3151537cf3042e7e7c756c259922f9fe539d6d5fcd42f44858498e632fa24f20020a246406
691044a169e7fdda738ba4c7cc6d31b88d298546a326b72c3e32a3bb5e2419e1
505770
6d5808d3c92a8c83af489df0d131bc391ae10c973ce96f18b0ac3d30eb93bb88916db394080f12cff19a6094b022304019bf27fd672b03c40eb7f18ba33fe71371eebbc4f0a8602e17c8b72083092cbaee1d11e946e76409908e25ea5331ea26c8b403ecdbd5f17ef969efc313c75bfec2467db528d263839e8f1c6cb91322429dcb11632b1e8641b8f41a935fdd330917fc136911d36ff29569ac9307a02553321008767d484f974f192cffd4865f492548cd4d4d1f0aedde8c27fa5acfff5f8bf1cedb03da33ea0c2743f6d30ff84048a0d3df2421379eb29859855a58314945f6667a2d884877cb68e92e7f9e052c085346419a469b4094ede8c9cae1b2af

Packet 6 (LP -> Target):
f87d9580097f99ed1d790ab2ca344dfd6bb2e82e5ad66bff12efaebf4ac3ee65

--- Packet 8 (target -> LP): Victim ID
4a72fcec13ae342581c01a64c37f758a5fa44744008ae71d9705d26fbe14425c03
691044a169e7fdda738ba4c7cc6d31b88d298546a326b72c3e32a3bb5e2419e1

--- Packet 9 (LP -> target): Escrow Address
66856d364071db14c444b76c6d7b0a6ce30529106e1d55e38dec4f523c5fde8804
03d6d113659423a4164e9CbaDc0f3AA619372291

Packet 10 (target -> LP): ????
31868c8f6cd3fa43c12e16edede62c65a3ef680417c73df5de8a899718bea312

Extracted data

Victim ID: 0x691044a169e7fdda738ba4c7cc6d31b88d298546a326b72c3e32a3bb5e2419e1
Encrypted Ransom Key: 6d5808d3c92a8c83af489df0d131bc391ae10c973ce96f18b0ac3d30eb93bb88916db394080f12cff19a6094b022304019bf27fd672b03c40eb7f18ba33fe71371eebbc4f0a8602e17c8b72083092cbaee1d11e946e76409908e25ea5331ea26c8b403ecdbd5f17ef969efc313c75bfec2467db528d263839e8f1c6cb91322429dcb11632b1e8641b8f41a935fdd330917fc136911d36ff29569ac9307a02553321008767d484f974f192cffd4865f492548cd4d4d1f0aedde8c27fa5acfff5f8bf1cedb03da33ea0c2743f6d30ff84048a0d3df2421379eb29859855a58314945f6667a2d884877cb68e92e7f9e052c085346419a469b4094ede8c9cae1b2af OTP Value (ASCII): 505770
Escrow Contract address: 0x03d6d113659423a4164e9CbaDc0f3AA619372291

Task 2

Found a string of characters being used as a kind of key for password generator function
OTP Secret Key: KLOZGSBPJ6FL2E7GD35AFZGMYTCK2ADE
HEX: 0x52dd93482f4f8abd13e61efa02e4ccc4c4ad0064

Task 3:

My Victim info:

VID: 691044a169e7fdda738ba4c7cc6d31b88d298546a326b72c3e32a3bb5e2419e1
IP: 10.36.100.6 | 0x0a246406 | 00001010.00100100.01100100.00000110
OTP: 505770 | 35 30 35 37 37 30 | 0x7b7aa
Key: 0x52dd93482f4f8abd13e61efa02e4ccc4c4ad0064

VID Generation breakdown

HMAC is called with a key in RSI (probably some variation of the secret Token, of len RDX [external param]); and with a 10 char message in RCX
-msg (qword) is half IP, half OTP-related string; probably IP first

HMAC_SHA256: msg=hex-version of IP + hex of OTP ascii |
key = hex of OTP secret key |

Target victim info:

{
"cpu_bits": "32",
"ip_address": "10.104.23.122", //0x0A68177A
"mac_address": "b6:76:84:16:46:5d",
"operating_system": "Linux",
"otp_value": "539366", //0x353339333636
"time_of_infection": "Mon, 13 Aug 2018 02:53:32 GMT" //1534128812
}

Generated victim ID: bdb05f047d975c5a6fc8bba0e0098dffd8df7a807c9648ceebf0581513fa7c55

Task 4:

Data retrieved from Blockchain:

Address of deployer: "0x63d85378eb4d57c4ae14f6a39b05e495de08b1a8"
Escrow balance: "0x1043561a8829300000" = 300 ETH
Registry Contract: "0x6b4e1e0755a93c6b60851dc72f4e32fa18ac6828"
# of tracked ransomContracts: 0xa (10)
Oracle address: "0x191b13d28df6b574275405e485dfc0f6794ad831"
MAX_PENDING = 0x6b

Encoding reference info for data retrival

var key = "0000000000000000000000000000000000000000000000000000000000000009"
web3.sha3(key, {"encoding": "hex"})
SHA3 of my VID [for indexes]: 0x55f191e6eb67eaa953b0342c4198d638865c3fd3cda3ef20c7f7b4e2565b7879

###Ransom contract addresses registered with Escrow Ransom array offset: "0x6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af" [...af - ...b9]
1: "0x000000000000000000000000b3ef278af18bfcba7a330f99d4f003961353b0c9"
2: "0x000000000000000000000000491ba26b330d6fd4574336ec9f31aab4d38b04e3"
3: "0x0000000000000000000000005a67fcb18208d4aba622c4a5a5c9f57622eb9363"
4: "0x000000000000000000000000432195d0f04bbee3cbaa5b00000e2d618c5e8ec7"
5: "0x00000000000000000000000062dfa887de01e458eb4b264362552c70fed5efd3"
6: "0x00000000000000000000000066c6703b5f2be3ec9cc8fe868fcc668099941be2"
7: "0x0000000000000000000000000560c5222bb11c1b074141b00916c0674625d2ab"
8: "0x0000000000000000000000007d2702f8223d2bd92d40502b8b0eb0444ddb146b"
9: "0x0000000000000000000000006e10c31957cb33510d20e5c7a428aad9543735e0"
10: "0x000000000000000000000000e915dc3e80838a22aa05a20f64434012c64ae9f5"

Cumulative data about all victims in Escrow

Victim IDs (Fullfilled?) [OTP] (On our network?)
1 "0x9d03e5845e1ebd9f2fe977e6086a9658f7cf1d1846506904dd92b2b9c021a5f7" (no) [0x94bcf, 609231] INFECTED: 10.36.22.54
2 "0xb832a270e7ad6d3f9c2fb7a96a7c5fbcddab790d5648c9dec8edb0f18baf07ef" (yes) [0x51b14, 334612] NO
3 "0xd81deea4af53107c1f2af8d67b081db165e9f6f0c93615f64002ad1419a73e2e" (no) [0x07663, 030307] NO
4 "0x1740e3c38c5c363c61ff63406fbf1d421fd78d27e7ad1806cc6b869eec40133e" (yes) [0xc4b71, 805745] NO
5 "0xc75be47366193afa692e95213e743d324af8121fa994ce8225d857f3134d5e28" (no) [0x91abb, 596667] NO
6 "0xbe84131a5bb8e4ce0e2fcb36341c01622be6d2f19775589338674efd3d6cd573" (no) [0xf353e, 996670] NO
7 "0xb9b27b734c67c4d2b903a499dbc3ed1912668ed2b3316bfd364157518c24b753" (yes) [0x86b48, 551752] NO
8 "0x96693b5ba6b473eb2cea68fb5648fe119f538b8d019ebcb3261570af8e8f6ca5" (no) [0x8d7c7, 579527] INFECTED 10.36.16.43
9 "0x91e2030e61115ee6a13eb26b067b0e9d59fe81677b9db5ba30fc124202a059e1" (no) [0xbfcbc, 785596] NO
10 "0x691044a169e7fdda738ba4c7cc6d31b88d298546a326b72c3e32a3bb5e2419e1" (no) [0x7b7aa, 505770] INFECTED 10.36.100.6

decKey for 2: 0xc1ed6f853f1347100d8061859858fb9fca102b101bcb7ce07b633e172a6e7b17

Task 5:

Need to get either OTPs associated with each victim ID (to make brute-force calculation of all possible victim IDs from subnet possible) or get IPs from other victims. Both might be possible to see in data sent in transactions for creating/authenticating ransom contracts.

Registry event topic? 0x75e933e6e9a09ae260f246bb811f2af1f0455b041a7ab91691968dcc4a28c892

New victim: chain of events:

  • LP connects to Ethereum and deploys (creates a new) Ransom contract for new victim (public constructor method)
  • Last step of Ransom constructor calls .registerVictim method in Registry (public method) with the VID and OTP
  • Registry adds victim to a pending auth map and emits an AuthEvent to let the Oracle know it needs to be processed (async)
  • AuthEvent contains the VID, Ransom contract addr [or wherever the call came from...] OTP, and origin [creater of event?]
  • Oracle uses the AuthEvent info to authenticate the victim- probs doesn't need IP, just ensures OTP matches timeframe
  • Orcale calls AuthCallback which ensures the returned VID and ransom addr match a VictimInfo mapping. Then adds their VInfo to the "authenticated" VictimMap and removes from AuthMap. Finally calls AuthCallbacks in Ransom and Escrow to link everything together.

See logResults.txt for event data. Use curl.sh to get all events from chunks of blocks, then search for VIDs in results.

AuthEvent(uint,address,uint,address)
Hash: "0x93448357776e05fe5c41725ce567220ac173b176e7437db8329b5fa4da007703"
Actual topic: 0x75e933e6e9a09ae260f246bb811f2af1f0455b041a7ab91691968dcc4a28c892

Finding infected IPs

Wrote C program to brute force generate VID's for every IP in our network range, using every OTP value in the Escrow. Compared to list of VIDs in Escrow and found these matches IP range: 10.36.0.0/16
Infected IPs:
10.36.22.54
10.36.16.43
10.36.100.6

Task 6:

Hacking brainstorms and observations

  • Authentication doesn't check if victim already exists? [Probably can't add new/dup victims since we might not have actual code for generating OTP from secret key. ]
  • Some methods aren't properly restricted (can be called by anyone but assume originate from one of the three contracts)?
  • RequestRefund doesn't check if contract was already fullfilled, should allow one victim to call for another? [moves out of escrow when fullfilled, might have to use diff function to retrieve stored in owneer]
  • decryptCallback() (oracle only) will transfer ransomAmount to victim if decrypt or authentication fails (assumes can only be called if ransom was paid...)

Escrow.decryptKey() [emits needed event] can only be called by Authenticated Ransom address- ie must have valid mapping from the sending address to a VID in Escrow.ransomMap. ALSO requires that the VID map to a valid Vstruct (with the same id) in Escrow.victimMap, AND that the money paid into Escrow.escrowMap[id] is >= the RansomAmmount in that Vstruct.

  • Would have to create a dummy Ransom contract that would successfully authenticate with the Oracle (need valid OTP) and would have a Ransom ammount of 0; would have to map it to an existing VID that already paid so that
  • Just create a duplicate of existing Ransom contract, but set authenticated and fulfilled to true in the constructor? Just need a way to get the address of the contract into the Escrow.ransomMap[] -> only possible through Escrow.AuthCallback(), which has to have the saved Registry address as its sender.

Figured out how to link the attacker's library code to my own C program to generate valid VIDs and OTPs
OTP only good for 30 seconds; changes on every :30 and :00

Rip the encryption key

Tried making a custom 'keyRipper' contract that just emits DecryptEvents (stealKey()) and captures the Oracle's response
Keyripper contract: 0xb8f930f0b030ce9de2f8c683d10b76f2d3488ea9
stealKey transaction hash: 0xc5f6a2cdbf6e6ab7cae53479a8fccb39fd7affc84e0a7daca9a8ebd25b5e99e2
Oracle never responded to the events; contract probably has to be authenticated

Tried adding several more contract variations, none of which would authenticate when deployed, so no Oracle interaction
New VID: 0x61d7a3c2be4dccac0113efb6534fa2deff724c7545987c2b70e5d18d070f9309 [035776]
Ransom Addr: 0x8f68ae202522c898a8bbc35ea5933ea7f1764e56
Ransom2: 0x79a3e9884f7083978d02b3e913cbf7bf757947cc [032542]
Ransom 3 unrestricted: 0xe2e9b553790b4b5a907726f7cac0c7f22ca1efe4 [717246]
Ransom 4 (orig ID, unrestricted): 0xaae05e419234dd0de1a2be0192debd41add57a12 [868578]

String that the "file" parameter of the ransom method is expecting (to pay ransom)
FILE: {"id":"691044a169e7fdda738ba4c7cc6d31b88d298546a326b72c3e32a3bb5e2419e1","iv":"e4f9f899d6ee6d0c840ed0a0","data":"9b9cd657df09784865f44981a11dee2a96f19838f15cd17bf0d57cf4c17c76aa631f67b7af2af6c9e227438331c7437fecf7c25feb46c507c6bfb3b1cb70ed6f12e186b514147379213c15ce66bf7f5b12e8fc64532003a1e95631ff2f13f7f335c8b7c5ae1a0d5b3613704f6dfb86f94b6e59bd79cae6cfb7537a38bdc70ec7f70fd914f6e61ffcef71cfcc6cc5c38a2df2bd408cf34fe00ccdf37897f603a2ca1a","tag":"be5cd81744369f1c8c85482cb5515763"}

Previous successful DecryptEvent pulled from Blockchain logs from other victims paying ransoms
Log:
[
{
"from": "0xb8f930f0b030ce9de2f8c683d10b76f2d3488ea9",
"topic": "0xc17195a10e83b996d2610d88f75a436776867170bc4a1c67e8af422a0e360ade",
"event": "DecryptEvent",
"args": {
"0": "47521592324735646538013269177716705927367302241010263928451952872720104167905",
"1": "6d5808d3c92a8c83af489df0d131bc391ae10c973ce96f18b0ac3d30eb93bb88916db394080f12cff19a6094b022304019bf27fd672b03c40eb7f18ba33fe71371eebbc4f0a8602e17c8b72083092cbaee1d11e946e76409908e25ea5331ea26c8b403ecdbd5f17ef969efc313c75bfec2467db528d263839e8f1c6cb91322429dcb11632b1e8641b8f41a935fdd330917fc136911d36ff29569ac9307a02553321008767d484f974f192cffd4865f492548cd4d4d1f0aedde8c27fa5acfff5f8bf1cedb03da33ea0c2743f6d30ff84048a0d3df2421379eb29859855a58314945f6667a2d884877cb68e92e7f9e052c085346419a469b4094ede8c9cae1b2af",
"2": "9b9cd657df09784865f44981a11dee2a96f19838f15cd17bf0d57cf4c17c76aa631f67b7af2af6c9e227438331c7437fecf7c25feb46c507c6bfb3b1cb70ed6f12e186b514147379213c15ce66bf7f5b12e8fc64532003a1e95631ff2f13f7f335c8b7c5ae1a0d5b3613704f6dfb86f94b6e59bd79cae6cfb7537a38bdc70ec7f70fd914f6e61ffcef71cfcc6cc5c38a2df2bd408cf34fe00ccdf37897f603a2ca1a",
"id": "47521592324735646538013269177716705927367302241010263928451952872720104167905",
"encKey": "6d5808d3c92a8c83af489df0d131bc391ae10c973ce96f18b0ac3d30eb93bb88916db394080f12cff19a6094b022304019bf27fd672b03c40eb7f18ba33fe71371eebbc4f0a8602e17c8b72083092cbaee1d11e946e76409908e25ea5331ea26c8b403ecdbd5f17ef969efc313c75bfec2467db528d263839e8f1c6cb91322429dcb11632b1e8641b8f41a935fdd330917fc136911d36ff29569ac9307a02553321008767d484f974f192cffd4865f492548cd4d4d1f0aedde8c27fa5acfff5f8bf1cedb03da33ea0c2743f6d30ff84048a0d3df2421379eb29859855a58314945f6667a2d884877cb68e92e7f9e052c085346419a469b4094ede8c9cae1b2af",
"encFile": "9b9cd657df09784865f44981a11dee2a96f19838f15cd17bf0d57cf4c17c76aa631f67b7af2af6c9e227438331c7437fecf7c25feb46c507c6bfb3b1cb70ed6f12e186b514147379213c15ce66bf7f5b12e8fc64532003a1e95631ff2f13f7f335c8b7c5ae1a0d5b3613704f6dfb86f94b6e59bd79cae6cfb7537a38bdc70ec7f70fd914f6e61ffcef71cfcc6cc5c38a2df2bd408cf34fe00ccdf37897f603a2ca1a",
"length": 3
}
}
]

Library analysis to run code in my program

get_totp_token parameters:
1[rdi]: base32 version of secret Key
2[rsi]: length of secret key after base32_decode [var_c0]
3[edx]: 32 bits returned from epochtime
4[rcx]: Pointer to var_bc; post-call result passed as 6th param to snprintf (so prob stores OTP value)
Return: int, 1 on success, 0 on failure

cid params:
1: IP address (probably hex in int)
2: ptr, probably store VID
3: ptr, store ~8bytes

EncKey Note: malware transmits encKey as raw hex (equal to actual base64 value). LP interprets that into base64, converts that to an ascii string, and store that string in the Ransom contract- where the ascii string is converted to its hex representation for storage.

Encrypted key for 2:
Base64: XaoHiPeMGg+QfKYoG9mPNFHq1TkXbhAkWzHd8ydEhuTNpl3tHAgrSnpP45r8aQm2u5hkHMyuMnjBuGiiFEWfKZEWCkyQHd5NjUR7XQq4H7g8By+OjIRdg6Sj0LNRGG0IakyMXet/0XUpkDwu1a8I5CDZ6IM4ErCwwthUdQHv/aAAfWJqoV7lWAkT49bx9dv6DuikF1p1neAzdkPjU5knhEu7+cTj0iwpXgjWCNaEIGMPpTwx4ljNsJhQJxdSqwYilETDO7ySDIs5SHO8aL+RzSpnH0mfIuYLaXM8KBMCLrGZevzh6DHb2fPzCkEEgjA3NlaFuD2TAiQ+ApockAr+LDw==
Hex:

EncKey for me:
Base64: bVgIw5PDiSrCjMKDwq9Iwp3DsMORMcK8ORrDoQzClzzDqW8YwrDCrD0ww6vCk8K7wojCkW3Cs8KUCA8Sw4/DscKaYMKUwrAiMEAZwr8nw71nKwPDhA7Ct8OxwovCoz/DpxNxw67Cu8OEw7DCqGAuF8OIwrcgwoMJLMK6w64dEcOpRsOnZAnCkMKOJcOqUzHDqibDiMK0A8Osw5vDlcOxfsO5acOvw4MTw4dbw77DgkZ9wrUow5JjwoPCnsKPHGzCuRMiQsKdw4sRYysewoZBwrjDtBrCk1/DnTMJF8O8E2kRw5Nvw7LClWnCrMKTB8KgJVMyEAh2fUhPwpdPGSzDv8OUwoZfSSVIw41NTR8Kw63DnsKMJ8O6WsOPw79fwovDscOOw5sDw5ozw6oMJ0PDtsOTD8O4QEjCoMOTw58kITfCnsKywphZwoVaWDFJRcO2ZnotwohId8OLaMOpLn/CngUsCFNGQcKaRsKbQMKUw63DqMOJw4rDocKywq8=

Stored EncKey for me: bVgI08kqjIOvSJ3w0TG8ORrhDJc86W8YsKw9MOuTu4iRbbOUCA8Sz/GaYJSwIjBAGb8n/WcrA8QOt/GLoz/nE3Huu8TwqGAuF8i3IIMJLLruHRHpRudkCZCOJepTMeomyLQD7NvV8X75ae/DE8db/sJGfbUo0mODno8cbLkTIkKdyxFjKx6GQbj0GpNf3TMJF/wTaRHTb/KVaayTB6AlUzIQCHZ9SE+XTxks/9SGX0klSM1NTR8K7d6MJ/paz/9fi/HO2wPaM+oMJ0P20w/4QEig098kITeesphZhVpYMUlF9mZ6LYhId8to6S5/ngUsCFNGQZpGm0CU7ejJyuGyrw==

String storage: 6256674930386b716a494f76534a3377305447384f527268444a633836573859734b77394d4f75547534695262624f55434138537a2f4761594a5377496a42414762386e2f5763724138514f742f474c6f7a2f6e4533487575385477714741754638693349494d4a4c4c7275485248705275646b435a434f4a6570544d656f6d794c5144374e76563858373561652f44453864622f734a476662556f306d4f446e6f3863624c6b54496b4b647978466a4b78364751626a3047704e6633544d4a462f775461524854622f4b56616179544236416c557a495143485a3953452b5854786b732f39534758306b6c534d314e5452384b3764364d4a2f70617a2f3966692f484f327750614d2b6f4d4a30503230772f34514569673039386b495465657370685a685670594d556c46396d5a364c5968496438746f3653352f6e67557343464e47515a70476d30435537656a4a7975477972773d3d0000000000000000

Encrypted file for 2:
{
"id":"b832a270e7ad6d3f9c2fb7a96a7c5fbcddab790d5648c9dec8edb0f18baf07ef",
"iv":"74e3b44a471fdf982649d5c5",
"data":"6a6b2920cb953a5b4b381ecb67535bcb583c58d0274f4ccd4f21d610268218d87817bb3867c92b017fcca506c0ecbb9441330ff9c516aa2c2555a7501a49b2d332619a086c72a8f8e9d94fec937777d39b9025692ad5d7b23ccaa2aa87ac0a59c0ffc1040727e75a3ec286507b6db6dd80cf4e8c9f9679a75d053c7e83a96cc02fba8c10db2d369331724f14753ddb6226f5c158a899a791a06a1f501b1b1de8b795",
"tag":"805ac227d06b6d7f6b1560c074245448"
}

(Escrow)

  • restrictSenderToVictim: guards both payRansom (submit ID of victim that already paid?) and requestRefund (transfer money to accounts other than the one who paid?). Could probably solve 6 and 7 if victimMap[] struct could be changed/re-pointed. Or maybe vicToPayerMap.
  • getDecryptionKey: could get keys for other accounts, but authenticated ransom contract probably prevents it.

---ANSWER---

Ransom constructor paramters:

  • 0x691044a169e7fdda738ba4c7cc6d31b88d298546a326b72c3e32a3bb5e2419e1
  • bVgI08kqjIOvSJ3w0TG8ORrhDJc86W8YsKw9MOuTu4iRbbOUCA8Sz/GaYJSwIjBAGb8n/WcrA8QOt/GLoz/nE3Huu8TwqGAuF8i3IIMJLLruHRHpRudkCZCOJepTMeomyLQD7NvV8X75ae/DE8db/sJGfbUo0mODno8cbLkTIkKdyxFjKx6GQbj0GpNf3TMJF/wTaRHTb/KVaayTB6AlUzIQCHZ9SE+XTxks/9SGX0klSM1NTR8K7d6MJ/paz/9fi/HO2wPaM+oMJ0P20w/4QEig098kITeesphZhVpYMUlF9mZ6LYhId8to6S5/ngUsCFNGQZpGm0CU7ejJyuGyrw==
  • 0x734eF4152bC53fC4559709BF11267F251e7531Aa
  • 0x6b4e1e0755a93c6b60851dc72f4e32fa18ac6828
  • 123456

Custom Ransom: Same VID, unrestricted functions, 0 ransom
Transaction hash: 0xe986610ad02ae95bb40c9d2caad7c3b76127116228db12d626fcabd22d0b6c5b
Address: 0xba94bc8dd2201344a0c3a4276427ab2f80d434c7 AUTH SUCCESS!

Pay ransom transaction hash: 0x0035cd6ca2dfbd25d8deaffd9d232912c0028a03606199d66f2339c3dad93a24
SUCCESS!

Task 7

Escrow line 214 (transfer RansomAmmount to my account, then to victims directly) can probably be exploited.

Python Ethereum storage retrieval:
w3.eth.getStorageAt(contract_address, Web3.sha3(hexstr=map_index + var_offset.zfill(64)))
EX) w3.eth.getStorageAt(escrow_address, Web3.sha3(hexstr=myVid + "3".zfill(64)))

WRONG ----------

PayRansom requires the amount sent to be >= RANSOMAMOUNT in actual contract [NOPE]; decryptCallback refunds the ransomAmount listed in Escrow's internal victim struct.

  • Set Ransom contract to have RANSOM=0, register same victim in Escrow with Ransom=300ETH. Pay ransom with invalid file. Profit.

Ransom-unrestricted-register @ 0x7dee6f4cb1167faaf5c22d2cce09d8c5f521f0ec
Deploy Transaction hash: 0x87c87f6dc8264a408c59a8baa5216561a4bdb7b9bc45bed18c48983f6db4eae1
AUTH SUCCESS!

RequestKeyTrap params:
0x0
0x0x1043561a8829300000
fdsa
0x1

First attempt: Transaction hash 0xd7322749789f247bb880e7f5c514d101bc662cabb2cf00fe43ab5eaa94946685
Doesn't seem to have worked

WRONG ----------

Escrow's payRansom transfers control to the Ransom contract (via requestKey) AFTER setting up the encFile mapping.

  • Register a new ransom amount (300 ETH) with the Escrow contract (use registerArbitraryRansom) inside the requestKey function before returning control to Escrow. On the callback, the invalid file/key will trigger a refund, which will refund the new ransom amount, rather than what's held in escrow (which would have been smarter for the hacker to do).
    NOPE: Escrow decryptKey checks that escrow contents are >= vicinfo ransomAmount.

Ransom-refunder @ 0xf08803aeede010e5a3cce741819b8073208f9002
Deploy transaction hash: 0x6bee36c28e291d89d55e3742ac931a10915f530ce03d9b537069c2337dfdf531
AUTH SUCCESS!

PayRansom traction failed.

  • E ransomMap is correct
  • E victimMap struct has correct 0 ether ransom

GOT IT! ----------

Need to change registered ransomAmount after Escrow decryptKey runs (emits event) but before decryptCallback triggers.

  • Would have to use two separate browsers and submit transactions right after each other before the oracle calls the callback.
  • Might not be possible to do- or at least not consistently.
  • Just re-register new ransom amount in modified requestKey function after generating the event!

Ransom-refunder2 @ 0x8e618127e04550598db4508f5f3a138cf6446ca8
Deploy transaction hash: 0x955434a011f782a15eacd610efe73a955c7480d9a24578590c7cbc8ee74630d7
Auth success!

Exploited payRansom call:
Transaction hash: 0x955434a011f782a15eacd610efe73a955c7480d9a24578590c7cbc8ee74630d7
Refund to self: Success!
Second call to claim residual 300,000 Wei (Tx hash): 0xcbec774174da1e337bcc64faae32ae037022e4d868cfcc263b3f625eac002125

Ether refunded to (transaction hash):
0xaB6f2E7a9471c22dC5F9E2e203c413Ab905b3687
0xFA651aB31831980b0351c5A701639E17DC4A8274
0xA2D636D4CaA650f70986b19F584fD5A940AA7A4C

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment