{
	"id": "52241ae0-2296-4329-8716-82a4209872c6",
	"created_at": "2026-04-06T00:17:53.397327Z",
	"updated_at": "2026-04-10T03:32:20.627073Z",
	"deleted_at": null,
	"sha1_hash": "74559b87e19605bfccf46bc2e4d951dbd80727f8",
	"title": "Winnti Group's skip-2.0: A Microsoft SQL Server backdoor",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 526179,
	"plain_text": "Winnti Group's skip-2.0: A Microsoft SQL Server backdoor\r\nBy Mathieu Tartare\r\nArchived: 2026-04-05 17:03:15 UTC\r\nFor a while, ESET researchers have been tracking the activities of the Winnti Group, active since at least 2012 and\r\nresponsible for high-profile supply-chain attacks against the video game and software industry. Recently, we discovered a\r\npreviously undocumented backdoor targeting Microsoft SQL (MSSQL) that allows attackers to maintain a very discreet\r\nfoothold inside compromised organizations. This backdoor bears multiple similarities to the PortReuse backdoor, another\r\ntool used by the Winnti Group that was first documented by ESET in October 2019, such as the use of the same custom\r\npacker and VMProtected launcher, which is why we attribute this backdoor to the Winnti Group.\r\nEarlier this year, we received a sample of this new backdoor called skip-2.0 by its authors and part of the Winnti Group’s\r\narsenal. This backdoor targets MSSQL Server 11 and 12, allowing the attacker to connect stealthily to any MSSQL account\r\nby using a magic password – while automatically hiding these connections from the logs. Such a backdoor could allow an\r\nattacker to stealthily copy, modify or delete database content. This could be used, for example, to manipulate in-game\r\ncurrencies for financial gain. In-game currency database manipulations by Winnti operators have already been reported. To\r\nthe best of our knowledge, skip-2.0 is the first MSSQL Server backdoor to be documented publicly. Note that even though\r\nMSSQL Server 11 and 12 are not the most recent versions (released in 2012 and 2014, respectively), they are the most\r\ncommonly used ones according to Censys's data.\r\nWe recently published a white paper updating our understanding of the arsenal of the Winnti Group, and that exposed a\r\npreviously undocumented backdoor of theirs called PortReuse. It uses an identical packer to that used with the payload\r\nembedded in compromised video games uncovered by ESET in March 2019. The VMProtected launcher that drops the\r\nPortReuse backdoor was also found being used to launch recent ShadowPad versions. In that context, we were able to find a\r\nnew tool called skip.2-0 by its developer. It uses the same VMProtected launcher as well as Winnti Group's custom packer\r\nand exhibits multiple similarities with other samples from the Winnti Group's toolset. This leads us to ascribe skip-2.0 to that\r\ntoolset also.\r\nThis article will focus on the technical details and functionality of this MSSQL Server backdoor, as well as on exposing the\r\ntechnical similarities of skip.2-0 with the Winnti Group's known arsenal – in particular, with the PortReuse backdoor and\r\nShadowPad. A note on the reasons why we chose the “Winnti Group” naming can be found on our white paper.\r\nVMProtected launcher\r\nWe found skip-2.0 while looking for VMProtected launchers, for which the payload is usually either PortReuse or\r\nShadowPad.\r\nEmbedded payload\r\nAs with the encrypted PortReuse and ShadowPad payloads, skip-2.0 is embedded in the VMProtected launcher's overlay, as\r\nshown in Figure 1:\r\nhttps://www.welivesecurity.com/2019/10/21/winnti-group-skip2-0-microsoft-sql-server-backdoor/\r\nPage 1 of 7\n\nFigure 1. VMProtected launcher's headers. The payload is embedded in the PE overlay.\r\nEncryption\r\nThe payload encryption is identical to that used in the other VMProtected launchers. It is RC5-encrypted with a key derived\r\nfrom the VolumeID and the string f@Ukd!rCto R$. – as described in our previous white paper on the Winnti Group arsenal.\r\nPersistence\r\nAs in the case of PortReuse and ShadowPad, the launcher probably persists by exploiting a DLL hijacking vulnerability by\r\nbeing installed at C:\\Windows\\System32\\TSVIPSrv.DLL. This results in the DLL being loaded by the standard Windows\r\nSessionEnv service at system startup.\r\nWinnti Group's custom packer\r\nOnce decrypted the embedded payload is actually Winnti Group's custom packer. This packer is the same shellcode that was\r\ndocumented in our previous article and white paper. It is used to pack the PortReuse backdoor as well as the payload\r\nembedded in the compromised video games.\r\nPacker configuration\r\nAs described in our previous article, the packer configuration contains the decryption key of the packed binary as well as its\r\noriginal filename, its size and the execution type (EXE or DLL). The payload's packer configuration is shown in Table 1.\r\nParent SHA-1 Payload SHA-1 RC4 key Filename\r\nL\r\nty\r\n9aafe81d07b3e5bb282608f0a2a4656eb485b7c9 a2571946ab181657eb825cde07188e8bcd689575 163716559\r\nInner-Loader.dll\r\n2\r\nTable 1. Payload's packer configuration\r\nOne can see from the packer configuration that the payload is called Inner-Loader. Inner-Loader is the name of an injector\r\nthat is the part of the Winnti Group’s arsenal used to inject the PortReuse backdoor into processes listening on a particular\r\nport, as described in our previous publication. Beyond that identical name, by analyzing this payload it appears that it is\r\nanother variant of the Inner-Loader injector.\r\nInner-Loader injector\r\nThis variant of Inner-Loader, instead of looking for a process listening on a particular port, as in the case when injecting the\r\nPortReuse backdoor, looks for a process called sqlserv.exe, which is the conventional process name of MSSQL Server. If\r\nfound, Inner-Loader then injects a payload into this process. This payload is also packed with the custom packer – the\r\npacker configuration of that payload is shown in Table 2.\r\nParent SHA-1 Payload SHA-1 RC4 key Filename\r\nL\r\nty\r\na2571946ab181657eb825cde07188e8bcd689575 60b9428d00be5ce562ff3d888441220290a6dac7 923567961\r\nskip-2.0.dll\r\n2\r\nTable 2. Packer configuration of the payload embedded in Inner-Loader\r\nThe original filename of this injected payload is skip-2.0.dll.\r\nskip-2.0\r\nhttps://www.welivesecurity.com/2019/10/21/winnti-group-skip2-0-microsoft-sql-server-backdoor/\r\nPage 2 of 7\n\nAfter having been injected and launched by Inner-Loader, skip-2.0 first checks whether it is executing within an sqlserv.exe\r\nprocess and if so, retrieves a handle to sqllang.dll, which is loaded by sqlserv.exe. It then proceeds to find and hook multiple\r\nfunctions from that DLL. Figure 2 depicts the skip-2.0 chain of compromise.\r\nFigure 2. skip-2.0 unpacking and injection\r\nHooking sqllang.dll\r\nThe hooking procedure used by skip-2.0 is very similar to the one used by NetAgent, the PortReuse module responsible for\r\ninstalling the networking hook. This hooking library is based on the distorm open source disassembler that is used by\r\nmultiple open source hooking frameworks. In particular, a disassembling library is needed to correctly compute the size of\r\nthe instructions to be hooked. One can see in Figure 3 that the hooking procedure used by NetAgent and skip-2.0 are almost\r\nidentical.\r\nhttps://www.welivesecurity.com/2019/10/21/winnti-group-skip2-0-microsoft-sql-server-backdoor/\r\nPage 3 of 7\n\nFigure 3. Hex-Rays output comparison between the NetAgent (left) and skip-2.0 (right) hooking procedures\r\nThere is one notable difference, which is the fact that the hooking function from skip-2.0 takes the address of the hook to be\r\ninstalled as an argument, while for NetAgent, the address of the hook to install is hardcoded. This is due to the fact that skip-2.0 has to hook multiple functions in sqllang.dll to operate properly, while NetAgent targets only a single function.\r\nTo locate each sqllang.dll function to be hooked, skip-2.0 first retrieves the size of the DLL once loaded in memory (i.e. its\r\nvirtual size) by parsing its PE headers. Then an array of bytes to be matched within sqllang.dll is initialized as shown in\r\nFigure 4. Once the address of the first occurrence matching the byte array is found, the hook is installed using the procedure\r\nshown in Figure 3.\r\nFigure 4. Hex-Rays output of the procedure initializing the byte array to match in sqllang.dll\r\nThe success of the hook installation is then logged in cleartext in a log file located at the hardcoded path\r\nC:\\Windows\\Temp\\TS_2CE1.tmp and shown in Figure 5.\r\nFigure 5. Log generated during hooks installation\r\nShould the targeted function not be found, the hook installer searches for a fallback function, with a different set of byte\r\npatterns.\r\nhttps://www.welivesecurity.com/2019/10/21/winnti-group-skip2-0-microsoft-sql-server-backdoor/\r\nPage 4 of 7\n\nMatching a sequence of bytes to locate the address of the targeted function instead of using a static offset, plus using a\r\nfallback sequence of bytes, allows skip-2.0 to be more resilient to MSSQL updates and to potentially target multiple\r\nsqllang.dll updates.\r\nOne password to rule them all\r\nThe functions targeted by skip-2.0 are related to authentication and event logging. The targeted functions include:\r\nCPwdPolicyManager::ValidatePwdForLogin\r\nCSECAuthenticate::AuthenticateLoginIdentity\r\nReportLoginSuccess\r\nIssueLoginSuccessReport\r\nFExecuteLogonTriggers\r\nXeSqlPkg::sql_statement_completed::Publish\r\nXeSqlPkg::sql_batch_completed::Publish\r\nSecAuditPkg::audit_event::Publish\r\nXeSqlPkg::login::Publish\r\nXeSqlPkg::ual_instrument_called::Publish\r\nThe most interesting function is the first one (CPwdPolicyManager::ValidatePwdForLogin), which is responsible for\r\nvalidating the password provided for a given user. This function's hook checks whether the password provided by the user\r\nmatches the magic password; if that is the case, the original function will not be called and the hook will return 0, allowing\r\nthe connection even though the correct password was not provided. A global flag is then set that will be checked by the other\r\nhooked functions responsible for event logging. The corresponding decompiled procedure is shown in Figure 6. In the case\r\nwhere this global flag is set, the hooked logging functions will silently return without calling their corresponding, original\r\nfunctions, so the action will not be logged. In the case where a different password is provided, the original function is called.\r\nFigure 6. Hex-Rays output of the procedure responsible for matching the password provided at login with the hardcoded\r\nstring\r\nA similar backdooring technique, based on hardcoded passwords, was used with SSH backdoors previously discovered by\r\nESET. The difference here is that skip-2.0 is installed in-memory, while in the case of the SSH backdoors the sshd\r\nexecutable was modified prior to execution.\r\nAdditionally, CSECAuthenticate::AuthenticateLoginIdentity will be called from within its hook code but the hook will\r\nalways return 0. The ReportLoginSucess and IssueLoginSuccessReport hooks will not call the original functions if the\r\nmagic password was used to log in. The same behavior is applied to FEExecuteLogonTriggers. Other logging functions such\r\nas XeSqlPkg::sql_statement_completed::Publish or XeSqlPkg::sql_batch_completed::Publish will also be disabled in the\r\ncase where the user logged in with the magic password. Multiple audit events are disabled as well, including\r\nSecAuditPkg::audit_event::Publish, XeSqlPkg::login::Publish and XeSqlPkg::ual_instrument_called::Publish.\r\nThis series of hooks allows the attacker not only to gain persistence in the victim's MSSQL Server through the use of a\r\nspecial password, but also to remain undetected thanks to the multiple log and event publishing mechanisms that are\r\ndisabled when that password is used.\r\nhttps://www.welivesecurity.com/2019/10/21/winnti-group-skip2-0-microsoft-sql-server-backdoor/\r\nPage 5 of 7\n\nWe tested skip-2.0 against multiple MSSQL Server versions and found that we were able to login successfully using the\r\nspecial password with MSSQL Server 11 and 12. To check whether a particular sqllang.dll version is targeted by skip-2.0\r\n(i.e., that matches the byte patterns), we created a YARA rule, which can be found in our GitHub repository.\r\nConnection with the Winnti Group\r\nWe observed multiple similarities between skip-2.0 and other tools from the Winnti Group's arsenal. Its VMProtected\r\nlauncher, custom packer, Inner-Loader injector and hooking framework are part of the already known toolset of the Winnti\r\nGroup. This leads us to think that skip-2.0 is also part of that toolset.\r\nConclusion\r\nThe skip-2.0 backdoor is an interesting addition to the Winnti Group’s arsenal, sharing a great deal of similarities with the\r\ngroup’s already known toolset, and allowing the attacker to achieve persistence on an MSSQL Server. Considering that\r\nadministrative privileges are required for installing the hooks, skip-2.0 must be used on already compromised MSSQL\r\nServers to achieve persistence and stealthiness.\r\nWe will continue to monitor new activities of the Winnti Group and will publish relevant information on our blog. For any\r\ninquiries, contact us at threatintel@eset.com.\r\nIndicators of Compromise (IoCs)\r\nComponent SHA-1 ESET detection name\r\nVMP Loader\r\n18E4FEB988CB95D71D81E1964AA6280E22361B9F\r\n4AF89296A15C1EA9068A279E05CC4A41B967C956\r\nWin64/Packed.VMProtect.HX\r\nInner-Loader injector A2571946AB181657EB825CDE07188E8BCD689575 Win64/Injector.BS\r\nskip-2.0 60B9428D00BE5CE562FF3D888441220290A6DAC7 Win32/Agent.SOK\r\nKnown targeted\r\nsqllang.dll files (non-exhaustive list)\r\n4396D3C904CD340984D474065959E8DD11915444\r\nBE352631E6A6A9D0B7BBA9B82D910FA5AB40C64E\r\nD4ADBC3F77ADE63B836FC4D9E5915A3479F09BD4\r\n0BBD3321F93F3DCDD2A332D1F0326142B3F4961A\r\nFAE6B48F1D6EDDEC79E62844C444FE3955411EE3\r\nA25B25FFA17E63C6884E28E96B487F58DF4502E7\r\nDE76419331381C390A758E634BF2E165A42D4807\r\nED08E9B4BA6C4B5A1F26D671AD212AA2FB0874A2\r\n1E1B0D91B37BAEBF77F85D1B7C640B8CC02FE11A\r\n59FB000D36612950FEBC36004F1317F7D000AA0B\r\n661DA36BDD115A1E649F3AAE11AD6F7D6FF2DB63\r\nN/A\r\nMITRE ATT\u0026CK techniques\r\nTactic ID Name Description\r\nExecution T1035 Service Execution\r\nskip-2.0 is started with the SessionEnv\r\nservice\r\nPersistence\r\nT1038 DLL Search Order Hijacking\r\nskip-2.0 probably uses a DLL hijacking\r\ntechnique against the SessionEnv service\r\nhttps://www.welivesecurity.com/2019/10/21/winnti-group-skip2-0-microsoft-sql-server-backdoor/\r\nPage 6 of 7\n\nTactic ID Name Description\r\nT1179 Hooking\r\nskip-2.0 hooks multiple functions in\r\nsqllang.dll service to bypass\r\nauthentication and maintain stealth\r\nDefense\r\nEvasion\r\nT1054 Indicator Blocking skip-2.0 blocks event logging\r\nT1045 Software Packing\r\nskip.2-0 and Inner-Loader are packed\r\nusing Winnti's custom packer. Further,\r\nthe launcher is VMProtected.\r\nDiscovery T1057 Process Discovery\r\nInner-Loader lists running processes in\r\norder to find the process running\r\nMSSQL Server\r\nImpact T1485 Data Destruction\r\nskip-2.0 allows unauthorized access to\r\nMSSQL databases, allowing data\r\ndestruction or tampering\r\nT1494\r\nRuntime Data\r\nManipulation\r\nskip-2.0 manipulates event logging at\r\nruntime\r\nT1492\r\nStored Data\r\nManipulation\r\nskip-2.0 allows unauthorized access\r\nto MSSQL databases, allowing\r\nmanipulation of stored data\r\nSource: https://www.welivesecurity.com/2019/10/21/winnti-group-skip2-0-microsoft-sql-server-backdoor/\r\nhttps://www.welivesecurity.com/2019/10/21/winnti-group-skip2-0-microsoft-sql-server-backdoor/\r\nPage 7 of 7",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"ETDA",
		"Malpedia"
	],
	"references": [
		"https://www.welivesecurity.com/2019/10/21/winnti-group-skip2-0-microsoft-sql-server-backdoor/"
	],
	"report_names": [
		"winnti-group-skip2-0-microsoft-sql-server-backdoor"
	],
	"threat_actors": [
		{
			"id": "5bbced13-72f7-40dc-8c41-dcce75bf885e",
			"created_at": "2022-10-25T15:50:23.695735Z",
			"updated_at": "2026-04-10T02:00:05.335976Z",
			"deleted_at": null,
			"main_name": "Winnti Group",
			"aliases": [
				"Winnti Group"
			],
			"source_name": "MITRE:Winnti Group",
			"tools": [
				"PipeMon",
				"Winnti for Windows",
				"PlugX"
			],
			"source_id": "MITRE",
			"reports": null
		},
		{
			"id": "4d5f939b-aea9-4a0e-8bff-003079a261ea",
			"created_at": "2023-01-06T13:46:39.04841Z",
			"updated_at": "2026-04-10T02:00:03.196806Z",
			"deleted_at": null,
			"main_name": "APT41",
			"aliases": [
				"WICKED PANDA",
				"BRONZE EXPORT",
				"Brass Typhoon",
				"TG-2633",
				"Leopard Typhoon",
				"G0096",
				"Grayfly",
				"BARIUM",
				"BRONZE ATLAS",
				"Red Kelpie",
				"G0044",
				"Earth Baku",
				"TA415",
				"WICKED SPIDER",
				"HOODOO",
				"Winnti",
				"Double Dragon"
			],
			"source_name": "MISPGALAXY:APT41",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "945a572f-ebe3-4e2f-a288-512fe751cfa8",
			"created_at": "2022-10-25T16:07:24.413971Z",
			"updated_at": "2026-04-10T02:00:04.97924Z",
			"deleted_at": null,
			"main_name": "Winnti Group",
			"aliases": [
				"G0044",
				"Leopard Typhoon",
				"Wicked Panda",
				"Winnti Group"
			],
			"source_name": "ETDA:Winnti Group",
			"tools": [
				"Agentemis",
				"BleDoor",
				"Cobalt Strike",
				"CobaltStrike",
				"FunnySwitch",
				"RbDoor",
				"RibDoor",
				"RouterGod",
				"Winnti",
				"cobeacon"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "2a24d664-6a72-4b4c-9f54-1553b64c453c",
			"created_at": "2025-08-07T02:03:24.553048Z",
			"updated_at": "2026-04-10T02:00:03.787296Z",
			"deleted_at": null,
			"main_name": "BRONZE ATLAS",
			"aliases": [
				"APT41 ",
				"BARIUM ",
				"Blackfly ",
				"Brass Typhoon",
				"CTG-2633",
				"Earth Baku ",
				"GREF",
				"Group 72 ",
				"Red Kelpie ",
				"TA415 ",
				"TG-2633 ",
				"Wicked Panda ",
				"Winnti"
			],
			"source_name": "Secureworks:BRONZE ATLAS",
			"tools": [
				"Acehash",
				"CCleaner v5.33 backdoor",
				"ChinaChopper",
				"Cobalt Strike",
				"DUSTPAN",
				"Dicey MSDN",
				"Dodgebox",
				"ForkPlayground",
				"HUC Proxy Malware (Htran)"
			],
			"source_id": "Secureworks",
			"reports": null
		}
	],
	"ts_created_at": 1775434673,
	"ts_updated_at": 1775791940,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/74559b87e19605bfccf46bc2e4d951dbd80727f8.pdf",
		"text": "https://archive.orkl.eu/74559b87e19605bfccf46bc2e4d951dbd80727f8.txt",
		"img": "https://archive.orkl.eu/74559b87e19605bfccf46bc2e4d951dbd80727f8.jpg"
	}
}