code-signing-final/All/Sign Using OV Cert.md

227 lines
7.5 KiB
Markdown
Raw Normal View 히스토리

2019-11-10 00:01:31 +00:00
# Purpose
2019-11-10 04:30:11 +00:00
We're going to be looking at how to create a server setup file that doesn't trigger any prompts that aren't user friendly. This setup file will contain another signed file that will launch a basic web server. The setup file will create the server file and a firewall rule for the server file. We will be building two files (`setup.go` and `server.go`) separately .
2019-11-10 00:01:31 +00:00
2019-11-10 04:30:11 +00:00
# The Server File
2019-11-10 00:01:31 +00:00
2019-11-10 04:30:11 +00:00
We're creating our web server file, building it and signing the application.
2019-11-10 00:01:31 +00:00
2019-11-10 04:30:11 +00:00
## Creating the Server File
2019-11-10 00:01:31 +00:00
2019-11-12 03:46:57 +00:00
Download `server.go` by running the following in a command prompt:
```
# Download the config file.
powershell "Invoke-WebRequest -OutFile b0x.json https://git.rootprojects.org/josh/code-signing-final/raw/branch/master/All/server.go"
```
https://git.rootprojects.org/josh/code-signing-final/raw/branch/master/All/serve.go
2019-11-10 04:30:11 +00:00
Create a file named `server.go` and add the following:
2019-11-10 00:01:31 +00:00
2019-11-10 04:30:11 +00:00
```
//go:generate goversioninfo
package main
import (
"flag"
"log"
"net/http"
)
func main() {
port := flag.String("p", "8100", "port to serve on")
directory := flag.String("d", ".", "the directory of static file to host")
flag.Parse()
http.Handle("/", http.FileServer(http.Dir(*directory)))
log.Printf("Serving %s on HTTP port: %s\n", *directory, *port)
log.Fatal(http.ListenAndServe(":"+*port, nil))
}
```
*Windows 10 will happily create server.go.txt if you don't turn off hidden file extensions and leave you wondering what's wrong with your Go install.*
First of all, you'll want to install Golang: https://golang.org/dl/
Then you'll want to install [goversioninfo](https://github.com/josephspurrier/goversioninfo) by running the following in a command prompt:
```
go get github.com/josephspurrier/goversioninfo/cmd/goversioninfo
```
This will allow us to set the name of the program, version, publisher name, etc.
```
# Add this to the top of your server go file.
//go:generate goversioninfo
# Then generate the configuration by running the following in a command prompt:
go generate
```
This will create a configuration file named `versioninfo.json` in the current directory. There are three things you will want to edit: 1. The version of the application, 2. The "publisher" or company name and 3. The product name.
![](versioninfo.png)
Near the top of the file, you will see `FileVersion` and `ProductVersion`.
You can set normal major, minor, patch and build versions for those values. The `FileVersion` is the version of the file and `ProductVersion` is the version of the application as a whole. You can most likely use the same version for both unless you're doing something unusual. You will set the same values again under `StringFileInfo`.
Next, you can set the "publisher name" by filling in the `CompanyName` value with the name of your organization.
Lastly, you can give your application a name, like "Go Web Server" under the `ProductName` value.
```
# Next, build your server app.
2019-11-12 01:10:00 +00:00
go build -o server.exe -ldflags "-s -w -H=windowsgui"
2019-11-10 04:30:11 +00:00
```
You will want to sign your application, the next section will show you how.
## Signing the Setup File
### Getting a Code Signing Certificate
Be aware that you will likely need to create a Dun & Bradstreet listing to get an "organization" code-signing certificate: https://www.dandb.com/businessdirectory/products/ (this is free)
You can purchase a code-signing certificate here: https://cheapsslsecurity.com/comodo/codesigningcertificate.html The validation process will take 1-3 business days if your information is correct and you give them your D-U-N-S (Dun & Bradstreet) number. After you receive an email containing a link to the certificate, follow these directions in the **exact same** browser as the one you used to request the certificate : https://cheapsslsecurity.com/downloads.aspx?ispdf=true&iscs=true&filenm=Comodo_Code_Signing_Collection_Guide.pdf
### Signing the File
[Screenshot] Next, you will need to install Visual Studio. You can download Visual Studio here: https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=Community&rel=16
In the install process, you will be greeted with this screen:
![](windowsdev.png)
Choose the "Universal Windows Platform Development" workload. After you have finished installing Visual Studio, open a "Developer Command Prompt for VS".
2019-11-10 00:01:31 +00:00
![](developerprompt.png)
```
# Sign a file with your certificate.
SignTool sign /t http://timestamp.comodoca.com /f codesigning.p12 /p <Password> file.exe
```
![](signfile.png)
You should see something like this:
![](donesigning.png)
2019-11-10 04:30:11 +00:00
# The Setup File
2019-11-10 00:01:31 +00:00
2019-11-10 04:30:11 +00:00
Now we're going to create the setup file that will create the firewall rule we need and "create" the server file for us.
2019-11-10 00:01:31 +00:00
2019-11-10 04:30:11 +00:00
## Firewall Rule
2019-11-10 00:01:31 +00:00
2019-11-10 04:30:11 +00:00
Create a file named `setup.go` and include the following:
2019-11-10 00:01:31 +00:00
```
2019-11-10 04:30:11 +00:00
//go:generate goversioninfo -manifest=setup.exe.manifest
2019-11-12 01:10:00 +00:00
//Add new firewall rule in Go.
2019-11-10 04:30:11 +00:00
package main
import (
"os"
2019-11-12 01:10:00 +00:00
"os/exec"
"io/ioutil"
"syscall"
2019-11-10 04:30:11 +00:00
"fmt"
"log"
2019-11-12 01:10:00 +00:00
"static" // Your fileb0x.
2019-11-10 00:14:39 +00:00
)
2019-11-10 04:30:11 +00:00
2019-11-10 00:14:39 +00:00
func main() {
2019-11-10 04:30:11 +00:00
// Grab files from virtual filesystem
files, err := static.WalkDirs("", false)
2019-11-10 00:01:31 +00:00
if err != nil {
log.Fatal(err)
2019-11-10 04:30:11 +00:00
log.Println("ALL FILES", files)
2019-11-10 00:01:31 +00:00
}
2019-11-10 04:30:11 +00:00
// here we'll read the file from the virtual file system
b, err := static.ReadFile("server.exe")
if err != nil {
log.Fatal(err)
}
2019-11-10 00:14:39 +00:00
2019-11-10 04:30:11 +00:00
// Copy file from virtual filesystem to real filesystem
err = ioutil.WriteFile("server.exe", b, 0644)
if err != nil {
fmt.Println("Error creating", "server.exe")
fmt.Println(err)
return
}
2019-11-10 00:14:39 +00:00
2019-11-12 01:10:00 +00:00
// Get current working directory and set it to 'dir'.
2019-11-10 04:30:11 +00:00
dir, err := os.Getwd()
if err != nil {
log.Fatal(err)
}
2019-11-12 01:10:00 +00:00
// Set server file path to 'file'
var file = "-Program '" + dir + "\\server.exe'"
//Create firewall rule
cmdinstance := exec.Command("powershell.exe", "-WindowStyle", "Hidden", "-Command", "New-NetFirewallRule", "-DisplayName", "'Go Web Server'", "-Direction", "Inbound", file, "-Action", "Allow")
cmdinstance.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} // Make it silent.
cmdoutput, cmderr := cmdinstance.Output()
if cmderr != nil {
fmt.Println(cmderr)
fmt.Println(cmdoutput)
}
2019-11-10 04:30:11 +00:00
}
```
2019-11-10 00:01:31 +00:00
2019-11-10 04:30:11 +00:00
Then create another file called `setup.exe.manifest` containing:
2019-11-10 00:01:31 +00:00
```
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
```
2019-11-10 04:30:11 +00:00
Rename `server.go` to `server.go_`
2019-11-12 01:10:00 +00:00
## Put the Server File In the Setup File
We need to install `fileb0x` to be able to store our server file (`server.exe`) in our setup file (`setup.exe`).
```
# Install fileb0x
go get -u github.com/UnnoTed/fileb0x
```
Download a pre-made configuration file by running this in the command prompt:
```
2019-11-12 03:46:57 +00:00
# Download the config file.
powershell "Invoke-WebRequest -OutFile b0x.json https://git.rootprojects.org/josh/code-signing-final/raw/branch/master/All/b0x.json"
2019-11-12 01:10:00 +00:00
```
```
# Create a fileb0x
fileb0x b0x.json
```
This will create a folder named `static` with a file in it. You will then need to copy that folder to your `$GOPATH/src/` (usually C:\Users\Username\Go\src\).
2019-11-10 04:30:11 +00:00
```
# Build the setup application.
go build -o setup.exe -ldflags "-s -w -H=windowsgui"
```
2019-11-12 01:10:00 +00:00
## WIP
2019-11-10 00:01:31 +00:00
2019-11-12 01:10:00 +00:00
Service: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/new-service?view=powershell-6
Credential seems to be what makes it admin or not: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/set-service?view=powershell-6