本文主要介绍了研究人员开发的一种用于识别SSH服务器是否被入侵的方法,该方法通过检查服务器上是否存在特定的恶意公钥来实现,而无需实际访问服务器。研究发现,大量系统存在已知的恶意公钥,从而揭示了潜在的安全风险,并讨论了RSA和Ed25519密钥的格式和使用。
当我登录到我的 Linux 服务器和 GitHub 时,我通常不使用用户名和密码。为此,我将我的公钥存储在服务器上,然后使用我的私钥来验证我的身份。
SSH 通常是组织用来访问远程系统的协议。这可能包括访问基于云的系统、GitHub 和 IoT 设备。因此,攻击者可以部署一组 SSH 公钥,这些公钥可用于提供对系统的访问权限。例如,Mirai 僵尸网络,它使用加载器和投放器系统来部署恶意公钥。
总的来说,Bob 将他的公钥存储在他想要登录的系统上,然后系统向他发送一条随机消息。然后他用他的私钥对这条消息进行签名,并将随机消息的签名发回。然后,Alice 根据公钥检查签名,如果签名通过验证,则允许 Bob 登录:
在这篇论文[1]中,研究人员开发了一种方法来识别 SSH 服务器是否已被入侵,同时不破坏服务器的安全性。这是通过检查服务器上是否存在特定的公钥来完成的[这里]:
总的来说,该研究团队确定了 21,700 个独特的系统,这些系统至少拥有 52 个可验证的恶意公钥中的一个——这些公钥来自 Bitdefender。这包括关键国家基础设施中的应用。
该论文指出,红线标识了客户端知道服务器上存在公钥的点:
图:识别系统上何时存在公钥 [1]
所用方法的优势在于,测试者无需访问服务器,只需确定系统上是否存在公钥即可。在测试中,发现 OpenSSH 9.4 和 7.4 是使用最广泛的 SSH 服务器,Censys 识别出全球超过 52% 的系统:
图:OpenSSH 扫描 [1]
在受损系统方面,我们可以看到中国的命中次数最多:
图:地理扫描 [1]
在威胁团队方面,六个密钥与 'teamtnt' 相关联,三个与 'mexalz' 相关联,一个与 'fritzfrog' P2P 僵尸网络 (MK01) 相关联,两个与 'coinminer' 僵尸网络 (MK40, MK43) 相关联,一个与 'mozi'、'hehbot' 和 'muhstick' 僵尸网络相关联。
我们的 RSA 密钥可能对贵组织的安全至关重要。为什么?好吧,如果贵公司与云有连接,那么你很可能会使用 SSH 连接到它。此外,如果你有 GitHub,贵公司通常会使用 OpenSSH 密钥对来验证你的身份。为此,我们创建一个 RSA 密钥对,然后将私钥存储在你的主机上,然后将公钥上传到服务器上。当你登录时,你用你的私钥对消息进行签名,服务器上的公钥会验证你的身份。一个典型的命令是:
$ ssh-keygen -t rsa -b 4096 -C "fred@home.com"
这将生成一个 4,096 位的密钥对。我们通常将私钥存储在 ./ssh 文件夹中,其中包含以下形式的公钥:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAXQMfdioW/ibO3rtEACYqplJjfYa2hSqQtfNIk4h
7Dah+IrHeiN0m8vr2ldkso2gqQpvxFArJZ2EAiRtMQVfeTyauhd5rk0x8H00AfQABJDq6grldiz
uYy5tCC7V2Fw==
私钥通常具有 PEM 形式:
-----BEGIN PRIVATE KEY-----
MIIB1QIBADANBgkqhkiG9w0BAQEFAASCAb8wggG7AgEAAl0DH3YqFv4mzt67RAAm
KqZSY32GtoUqkLXzSJOIew2ofiKx3ojdJvL69pXZLKNoKkKb8RQKyWdhAIkbTEFX
3k8mroXea5NMfB9NAH0AASQ6uoK5XYs7mMubQgu1dhcCAwEAAQJdAjrb+LAUaQe8
+cFTze0UeK48Ow5nxn4wvniriIA9v3vaMGJ0Hl6qkFO1qq76O+uvSehxPHnzBrfs
SXkQ8nScyeGpoTpn0DCnMnFRiY1hAMy6SqVdC4t7UP9u6oCBAi8B+POU6nCyUOnL
FlPVGFoBxSoxC7q7tJytq+xaPfGBN63AT3sdnXm06YAH1uE/1wIvAZVPf+1sDjIP
c4hFNPzIPh/x1M3qDN9eBr6tdPwymuPmpQ1lik/b9ZpMfXGns8ECLwDTVfcci+BF
tyP1i06jq4AUKg1u8E+BTxXs37YBOOOxDvpvCYMiln6eP6SITavvAi8A6n71d8rl
p6by4+uOjZXZA6hpw7zfN7hx1I4MugEZRjPiWI7f5/ZN8bjBdylcwQIvAQp1f9vQ
S+P5ktRlO7vEm10LtKotJ85Rp+le7PX56re+nntKVZFsliKW0yPmWJE=
-----END PRIVATE KEY-----
使用 RSA,我们生成一个私钥和一个公钥。公钥可用于加密数据,私钥可用于解密数据。我们还可以使用私钥对数据进行签名,并使用公钥来验证签名。使用我们的 RSA 密钥,有多种格式可用于密钥。
对于私钥,我们可以使用 DER 或 PEM 编码。使用 DER,我们有二进制编码,使用 PEM,我们有 Base64 编码。对于私钥格式,我们通常使用 PKCS8 或 OpenSSH 格式。对于公钥格式,我们通常使用 PKCS1 或 OpenSSH 格式。PKCS1 (RFC 8017 [这里]) 用于 RSA 公钥,PKCS8 (RFC 5208 [这里]) 用于 RSA 私钥。当使用 OpenSSH 时,使用 OpenSSH 格式。
对于私钥的 PKCS8 格式和公钥的 PKCS1 格式,我们有[这里]:
Private key encoding: Encoding.PEM
Private key format: PrivateFormat.PKCS8
Public key encoding: Encoding.PEM
Public key format: PublicFormat.PKCS1
Curve: RSA
Key size: 512
Private key:
-----BEGIN PRIVATE KEY-----
MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAolXeu/Z3CmsQ3+cC
oUU0/ckmNmOzfCfHcxbOsvIg0W+ZCw9Dunqkwu8n+DOv52y4sVucPN4/n1h/5wT/
LwK1gQIDAQABAkAKHHMdHgLYIUcRyx+8z8S3MfoxVRBu4UNpBbimKLKmmMV2UqIK
IbTzithZWol8YZVOzwe6GZqZdbWsN2A/99fJAiEA0RYqbzrG+rj/JNN+uB2onIJ5
hX04p7F4R6naoRw/sC8CIQDGwlcSqdyciiNx4mzLNBADkxRaKIwWa4k5/+P5BNVZ
TwIhAJbTAXtJD/4OcuZytedEZbu4lsaHZNX6vAQd73rmcL67AiEAqqLdriA2Tg4q
L/N8A1hHB0qWBnEZE4Zu4WRWi8sifvECIHOwaiu894SZOXT/oVWUe1Tt8TTUkjh3
vrzFEngj1KH1
-----END PRIVATE KEY-----
Public key:
-----BEGIN RSA PUBLIC KEY-----
MEgCQQCiVd679ncKaxDf5wKhRTT9ySY2Y7N8J8dzFs6y8iDRb5kLD0O6eqTC7yf4
M6/nbLixW5w83j+fWH/nBP8vArWBAgMBAAE=
-----END RSA PUBLIC KEY-----
== Key details ==
Private key p: 94572548861418413170793281130206948262270743656077910281902919609818141405231
Private key q: 89901313305153493837701246798962325038348122110633117471237293551165111621967
Private key d: 529562926001195601356684301698866326413345712090993164221410379202037190321577763828933217411281353522563929370506825155100138444226272376429593583146953
Private key dmp1: 68219742243672360386487821618788371135371613078735419817461289417491686145723
Private key dmq1: 77180943464015078158664921340568171505525409195304358170219800789824890371825
Private key iqmp: 52327675434767630609908503478553704202898127769459895123317013029443897434613
Public key N: 8502196345257314092629353032934493491952826539271783195389165120471315860388533789897638465459959515059108061765928203429656415393078278070600051028309377
Public key e: 65537
For a PKCS8 format for the private key and OpenSSL for the public key we have:
Private key encoding: Encoding.PEM
Private key format: PrivateFormat.PKCS8
Public key encoding: Encoding.OpenSSH
Public key format: PublicFormat.OpenSSH
Curve: RSA
Key size: 512
Private key:
-----BEGIN PRIVATE KEY-----
MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAmrlxD5nriWnx6sjq
RShGE09rODVfsOf8eM9LoQmGuKMVyYwiLzBxfb/9fI/85mGZ5lz4q99/aYRMzDEW
1b7ztQIDAQABAkAKQqXmvPRLpoTuZuhyMZuECE456gAwgRHTCRwgz7rpX3zXJHDj
u9eTb72M6xpySSVzzm4dnyApDI3cczH8KVhBAiEAzdrjWtUasmUNsVbSyN32x3ZQ
oRH3qQ7ygj8ZSZQSmz0CIQDAagxTasVSwRYkSfxi9QCw7HZB69Pwu5o4Slm/3Tih
2QIgeZpGF9AvNxbO4eWCGrpUHzvbIWr1u95ij2Iq0/Yuj5kCIHr2CkRwkgMNY3Hz
Wfd/LF7j7bq40ysfKDHayboDzEIZAiEAtCaFTAi6jwlNH8eiDGJGcQpLQHZszbzC
RE93Czur8RE=
-----END PRIVATE KEY-----
Public key:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAQQCauXEPmeuJafHqyOpFKEYTT2s4NV+w5/x4z0uhCYa4oxXJjCIvMHF9v/18j/zmYZnmXPir339phEzMMRbVvvO1
== Key details ==
Private key p: 93110875764949719476238107672919838687628633107480967655388250638667882863421
Private key q: 87031437786729667164140930047172401841167023011440001381225829497798292709849
Private key d: 537377816486057093623489898048742650307780775209058960854798861864356041641982701729791124202966316352993094018697228194170186627346400257856269332338753
Private key dmp1: 55002432890798532734227720225970347055142208250652580707244773719050130722713
Private key dmq1: 55616882767688865686579890616073780635517586870655029950213146241013325251097
Private key iqmp: 81484372915588842505944083993148404899258637724832461768066878335252901392657
Public key N: 8103573391405136618684458685784732414454907654136239557648631617580373193992499590832953636793406019816852260372917254966135377710040073283801059648533429
Public key e: 65537
我们越来越多地看到 Ed25519 用于签名。它使用曲线 y ²2= x ³+486662 x ²+ x[plot],这是一条 Montgomery 曲线。使用的素数是 2255−19。此页面生成一个 Ed25519 密钥对,并以各种格式显示私钥和公钥。私钥是一个随机标量值 (a),公钥是:
Pk = a. G
其中 G 是曲线上的基点。这通常是一个 (x,y) 点,但在 Curve 25519 中,我们只需要存储 x 值。因此,私钥的大小与公钥相同。
$ ssh-keygen -t ed25519 -C "fred@home.com"
这将生成一个 Ed25519 密钥对。我们通常将私钥存储在 ./ssh 文件夹中,其中包含以下形式的公钥:
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFP7xLB1QQNFqgh3KXymNzmDU4OlLBybR7BWwgcL4R+c
uYy5tCC7V2Fw==
私钥通常具有 PEM 形式:
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIL6m8j7OWZiZj8xC4Gx7qaMwy23LcWZqLoytC/DLLOst
-----END PRIVATE KEY-----
使用 EdDSA,我们生成一个私钥和一个公钥。我们使用私钥对数据进行签名,并使用公钥来验证签名。使用我们的 EdDSA 密钥,有多种格式可用于密钥。
对于私钥,我们可以使用 DER、PEM 或 Raw 编码。使用 DER,我们有二进制编码,使用 PEM,我们有 Base64 编码,对于 Raw,我们获得原始二进制标量值。对于私钥格式,我们通常使用 PublicKeyInfo、OpenSSH 或 Raw 格式。对于公钥格式,当使用 OpenSSH 时,我们通常使用 OpenSSH 格式。
公钥和私钥的原始格式是:
Private key encoding: Encoding.Raw
Private key format: PrivateFormat.Raw
Public key encoding: Encoding.Raw
Public key format: PublicFormat.Raw
Private key:
308edd7fca562182adbffaa59264a138d9e04f9f3adbda2c80ef1ca71b7dcfa4
Public key:
a06042d815cab4e60f0bc3e5baa6cdb599a5dbd85ab593c5fbd4af80c985f5d1
对于具有 OpenSSH 格式的公钥,我们得到:
Private key encoding: Encoding.Raw
Private key format: PrivateFormat.Raw
Public key encoding: Encoding.OpenSSH
Public key format: PublicFormat.OpenSSH
Private key:
3154ff11e34ba6494d03151189e4d7705ef6fe7d417b7ba9cfce82d55aa1eb99
Public key:
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKgYa4mZmicb0SyyptNV0bAe96QrWWdS9ckhvmFcnFde
对于私钥和公钥的 PEM 格式:
Private key encoding: Encoding.PEM
Private key format: PrivateFormat.PKCS8
Public key encoding: Encoding.PEM
Public key format: PublicFormat.SubjectPublicKeyInfo
Private key:
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIDGbusIw21Mq7BoGMjluljkvYRFX+35R1YMI/ig/ofuK
-----END PRIVATE KEY-----
Public key:
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEA7GzoeIO9cCOKVHXWu76FfNzmb1dklaO6Cx7li5BOTVc=
-----END PUBLIC KEY----
有一种很棒的新方法可以对你的系统(以及你可能连接到的系统)进行扫描。
[1] Munteanu, C., Smaragdakis, G., Feldmann, A., & Fiebig, T. (2025). 第 22 条军规:使用 SSH 公钥发现受损主机。在 第34届 USENIX 安全研讨会 中。USENIX.
- 原文链接: medium.com/asecuritysite...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!