วิธีการถอดรหัส Jenkins รหัสผ่านจาก credentials.xml?


37

ฉันได้เข้าร่วมโครงการที่หนังสือรับรองเจนกินส์จำนวนมากมีรหัสผ่านหรือสตริงข้อความรหัสผ่านที่ฉันต้องรู้เพื่อดำเนินการต่อกับโครงการโชคไม่ดีที่เอกสารเหล่านี้ไม่ได้ถูกบันทึกไว้ที่ใดเลย

ฉันได้ตรวจสอบcredentials.xmlไฟล์ที่จัดเก็บข้อมูลรับรองเหล่านี้แล้ว แต่ไม่ได้เป็นข้อความธรรมดาเช่น:

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

หมายเหตุ: ฉันเปลี่ยนมันเล็กน้อยเพื่อความเป็นส่วนตัว

ฉันจะถอดรหัสรหัสผ่านเดิมตามสตริงด้านบนได้อย่างไร


ฉันได้รับข้อผิดพลาดกับคำตอบที่เสนอ: println (hudson.util.Secret.decrypt ("{{xxx / wwww + yyyy / zzzz =}}")) สัญลักษณ์ + กำลังทำลายสคริปต์ ข้อเสนอแนะใด ๆ
Jay Bau

@JayBau ลองด้วยวงเล็บเดียว: "{...}"ลบอีกครั้ง
kenorb

คำตอบ:


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.


สำหรับรายละเอียดเพิ่มเติมตรวจสอบ: การจัดเก็บข้อมูลประจำตัวในเจนกินส์


7

นี่เป็นตัวอย่างสั้น ๆ ที่คุณสามารถเรียกใช้จากคอนโซลสคริปต์เจนกินส์เพื่อถ่ายโอนข้อมูลประจำตัวของคุณทั้งหมดไปเป็นข้อความธรรมดา

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 ฉันได้เพิ่มอีกตัวอย่าง
แมกนัส

ขอบคุณมาก :-)
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))
  }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.