Как расшифровать пароли Jenkins из credentials.xml?


37

Я взял на себя проект, в котором у многих учетных данных Jenkins есть пароли или строки парольных фраз, которые мне нужно знать, чтобы продолжить работу над проектом, к сожалению, они нигде не были задокументированы.

Я проверил credentials.xmlфайл, где хранятся эти учетные данные, но они не в виде простого текста, например:

<passphrase>{AAAAAAAAAAAANzxft/rDzyt8mhxpn3O72dxvVqZksL5vBJ4jNKvAjAA=}</passphrase>

Примечание: я немного изменил его из соображений конфиденциальности.

Как я могу расшифровать его оригинальный пароль на основе приведенной выше строки?


Я получаю сообщение об ошибке с предложенным ответом: println (hudson.util.Secret.decrypt ("{{xxx / wwww + yyyy / zzzz =}}")) Символ + нарушает работу сценария. Любое предложение?
Джей Бау

@JayBau Попробуйте с одинарными скобками: "{...}"удалите лишние один раз.
Кенорб

Ответы:


46

К счастью, есть hudson.util.Secret.decrypt()функция, которая может быть использована для этого, поэтому:

  1. В Дженкинс, перейдите на /scriptстраницу.
  2. Запустите следующую команду:

    println(hudson.util.Secret.decrypt("{XXX=}"))
    

    или:

    println(hudson.util.Secret.fromString("{XXX=}").getPlainText())
    

    где {XXX=}ваш зашифрованный пароль Это напечатает простой пароль.

    Чтобы сделать наоборот, запустите:

    println(hudson.util.Secret.fromString("some_text").getEncryptedValue())
    

Источник: суть вtuxfight3r/jenkins-decrypt.groovy .


Кроме того, проверьте следующие сценарии: tweksteen/jenkins-decrypt, menski/jenkins-decrypt.py.


Для получения более подробной информации, проверьте: хранилище учетных данных в Jenkins .


7

Вот небольшой фрагмент кода, который вы можете просто запустить из консоли сценария jenkins, чтобы вывести все свои учетные данные в обычный текст.

com.cloudbees.plugins.credentials.SystemCredentialsProvider.getInstance().getCredentials().forEach{
  it.properties.each { prop, val ->
    println(prop + ' = "' + val + '"')
  }
  println("-----------------------")
}

Более сложная версия, в которой перечислены несистемные поставщики учетных данных:

import com.cloudbees.plugins.credentials.CredentialsProvider
import com.cloudbees.plugins.credentials.Credentials
import com.cloudbees.plugins.credentials.domains.Domain
import jenkins.model.Jenkins
def indent = { String text, int indentationCount ->
  def replacement = "\t" * indentationCount
  text.replaceAll("(?m)^", replacement)
}

Jenkins.get().allItems().collectMany{ CredentialsProvider.lookupStores(it).toList()}.unique().forEach { store ->
  Map<Domain, List<Credentials>> domainCreds = [:]
  store.domains.each { domainCreds.put(it, store.getCredentials(it))}
  if (domainCreds.collectMany{ it.value}.empty) {
    return
  }
  def shortenedClassName = store.getClass().name.substring(store.getClass().name.lastIndexOf(".") + 1)
  println "Credentials for store context: ${store.contextDisplayName}, of type $shortenedClassName"
  domainCreds.forEach { domain , creds ->
    println indent("Domain: ${domain.name}", 1)
    creds.each { cred ->
      cred.properties.each { prop, val ->
        println indent("$prop = \"$val\"", 2)
      }
      println indent("-----------------------", 2)
    }
  }
}

Как изменить это, чтобы получить учетные данные из всех доменов, из всех папок?
Джмари

@jmary Я добавил еще один пример
Магнус

Большое спасибо :-)
jmary

1

Для записи, следующий фрагмент, который нужно вставить в консоль, также выполняет свою работу:

def creds = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
    com.cloudbees.plugins.credentials.common.StandardUsernameCredentials.class,
    Jenkins.instance,
    null,
    null
)

for(c in creds) {
  if(c instanceof com.cloudbees.jenkins.plugins.sshcredentials.impl.BasicSSHUserPrivateKey){
    println(String.format("id=%s  desc=%s key=%s\n", c.id, c.description, c.privateKeySource.getPrivateKeys()))
  }
  if (c instanceof com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl){
    println(String.format("id=%s  desc=%s user=%s pass=%s\n", c.id, c.description, c.username, c.password))
  }
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.