Skip to content

Instantly share code, notes, and snippets.

@HarmJ0y
Created November 2, 2020 23:15
Show Gist options
  • Save HarmJ0y/a8a5fe987f2b7751eb2ce55c2eec155d to your computer and use it in GitHub Desktop.
Save HarmJ0y/a8a5fe987f2b7751eb2ce55c2eec155d to your computer and use it in GitHub Desktop.
Rubeus Jenkinsfile
@Library('ci-jenkins-common') _
// Jenkins build pipeline (declarative)
// Project: Seatbelt
// URL: https://github.com/GhostPack/Seatbelt
// Author: @tifkin_/@harmj0y
// Pipeline Author: harmj0y
def gitURL = "https://github.com/GhostPack/Seatbelt"
def commitHash = "08314908a5676f597722d8f374cd3a74220638b4"; // Oct 19, 2020
pipeline {
// run everything on an existing agent configured with a label 'windows'
agent { label 'windows' }
options {
// add timestamps to the console log
timestamps()
// discard old builds, keeping a max number of 5 builds
buildDiscarder(logRotator(numToKeepStr: '5'))
}
// Note: parameters/options don't appear until the job is run once
parameters {
// unique project ID that's used to track the build runs
string name: 'ProjectID', defaultValue: 'Master', description: 'ProjectID associated with the build.', trim: true
}
stages {
stage('checkout') {
steps {
// clone the code base with up to 5 retries on failure
script {
try {
checkout([
$class: 'GitSCM',
branches: [[name: "${commitHash}"]],
doGenerateSubmoduleConfigurations: false,
extensions: [[$class: 'CleanBeforeCheckout']],
submoduleCfg: [],
userRemoteConfigs: [[url: "${gitURL}"]]
])
}
catch(error) {
echo "Clone of ${gitURL} failed: ${error} . Retrying."
retry(5) {
checkout([
$class: 'GitSCM',
branches: [[name: "${commitHash}"]],
doGenerateSubmoduleConfigurations: false,
extensions: [[$class: 'CleanBeforeCheckout']],
submoduleCfg: [],
userRemoteConfigs: [[url: "${gitURL}"]]
])
}
}
}
}
}
stage('prep') {
steps {
// common function to replace a known "bad" term
replaceAll("*.cs", "Mimikatz", "PROJECT")
script {
// replace AssemblyInfo.cs with a clean one
replaceAssemblyInfo()
// replace the assembly name
replaceAssemblyName()
}
}
}
stage('build') {
steps {
script {
// build the project for .NET 3.5 and 4.0
// 'ci-jenkins-common' library function -> 'msbuild("PROJECT.sln", ".NET_VERSION")'
msbuild("${JOB_NAME}.sln", "3.5")
msbuild("${JOB_NAME}.sln", "4.0")
}
// rename the build output binaries to "{JOB_NAME}_{.NET_VERSION}.exe"
fileOperations(
[
fileRenameOperation(
source: "${JOB_NAME}/bin/3.5/${JOB_NAME}.exe",
destination: "${JOB_NAME}/bin/3.5/${JOB_NAME}_3.5.exe"
),
fileRenameOperation(
source: "${JOB_NAME}/bin/4.0/${JOB_NAME}.exe",
destination: "${JOB_NAME}/bin/4.0/${JOB_NAME}_4.0.exe"
)
]
)
}
}
stage('obfuscation') {
steps {
script {
// obfuscate the binary using a 'ci-jenkins-common' library function
obfuscateDotnetBinary("3.5", "Seatbelt", "Seatbelt")
obfuscateDotnetBinary("4.0", "Seatbelt", "Seatbelt")
}
}
}
stage('opsec tests') {
steps {
script {
// test the build artifacts using a 'ci-jenkins-common' library function
testOpsec("${JOB_NAME}\\bin\\3.5\\${JOB_NAME}_3.5.exe")
testOpsec("${JOB_NAME}\\bin\\3.5\\${JOB_NAME}_3.5_obf.exe")
testOpsec("${JOB_NAME}\\bin\\4.0\\${JOB_NAME}_4.0.exe")
testOpsec("${JOB_NAME}\\bin\\4.0\\${JOB_NAME}_4.0_obf.exe")
}
}
}
stage('fingerprinting') {
steps {
script {
// fingerprint the build artifacts using a 'ci-jenkins-common' library function
fingerprintArtifact("${JOB_NAME}\\bin\\3.5\\${JOB_NAME}_3.5.exe")
fingerprintArtifact("${JOB_NAME}\\bin\\3.5\\${JOB_NAME}_3.5_obf.exe")
fingerprintArtifact("${JOB_NAME}\\bin\\4.0\\${JOB_NAME}_4.0.exe")
fingerprintArtifact("${JOB_NAME}\\bin\\4.0\\${JOB_NAME}_4.0_obf.exe")
}
}
}
// Publish to Artifactory
// Note: have to use ${params.PARAM_NAME} syntax here to access a parameter value (instead of an env var)
stage('publish') {
steps {
rtBuildInfo()
script {
bat 'git rev-parse HEAD > commit'
def commit = readFile('commit').trim()
rtUpload (
serverId: "artifactory-prod",
spec:
"""{
"files": [
{
"pattern": "*/bin/*/*_*.exe",
"target": "OffensiveToolkit/Projects/${params.ProjectID}/",
"props": "language=csharp;ext=exe;type=postex;ProjectID=${params.ProjectID};rev=${commit}"
},
{
"pattern": "*.iocs",
"target": "IOCS/Projects/${params.ProjectID}/",
"props": "language=iocs;ext=iocs;type=iocs;ProjectID=${params.ProjectID};rev=${commit}"
},
{
"pattern": "*.iocs",
"target": "IOCS/Tools/${JOB_NAME}/${BUILD_NUMBER}/",
"props": "language=iocs;ext=iocs;type=iocs;ProjectID=${params.ProjectID};rev=${commit}"
}
]
}"""
)
}
}
}
}
post {
always {
// report the report results
nunit testResultsPattern: '*/bin/*/*.exe.xml'
}
success {
// archive the artifacts
archiveArtifacts artifacts: '*/bin/*/*_*.exe', fingerprint: true
}
cleanup {
// clean up our workspace
deleteDir()
// clean up tmp directory
dir("${workspace}@tmp") {
deleteDir()
}
// clean up script directory
dir("${workspace}@script") {
deleteDir()
}
// clean up libs directory
dir("${workspace}@libs") {
deleteDir()
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment