|
Size: 2401
Comment:
|
← Revision 7 as of 2026-10-04 10:02:05 ⇥
Size: 11140
Comment:
|
| Deletions are marked like this. | Additions are marked like this. |
| Line 11: | Line 11: |
| ./CSETWebNg/Dockerfile ./CSETWebApi/Dockerfile |
#./CSETWebNg/Dockerfile #./CSETWebApi/Dockerfile |
| Line 77: | Line 77: |
After the database is restored we can access http://localhost:4200/ . We need to create a user to login. == Install dotnet 10 in debian == {{{#!highlight sh # https://dotnet.microsoft.com/en-us/download/dotnet/10.0 # https://learn.microsoft.com/pt-pt/dotnet/core/install/linux-debian?tabs=dotnet10 cd ~ wget https://packages.microsoft.com/config/debian/13/packages-microsoft-prod.deb -O packages-microsoft-prod.deb sudo dpkg -i packages-microsoft-prod.deb rm packages-microsoft-prod.deb sudo apt-get update && sudo apt-get install -y dotnet-sdk-10.0 dotnet --version }}} == cset-adduser-console == {{{#!highlight sh cd ~ mkdir cset-adduser-console cd cset-adduser-console dotnet new console }}} '''Dockerfile''' {{{#!highlight sh FROM mcr.microsoft.com/dotnet/sdk:10.0 WORKDIR /app RUN apt-get update RUN apt-get install net-tools procps vim nano -y CMD tail -f /var/log/lastlog }}} '''cset-adduser-console.csproj''' {{{#!highlight xml <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net10.0</TargetFramework> <RootNamespace>cset_adduser_console</RootNamespace> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.27" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.1" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.4" /> <PackageReference Include="System.CommandLine" Version="2.0.8" /> <PackageReference Include="System.Windows.Extensions" Version="8.0.0" /> </ItemGroup> </Project> }}} '''Program.cs''' Adapted from CSETAddUser {{{#!highlight csharp using System.Text; using System.Security.Cryptography; using Microsoft.Data.SqlClient; using System.Data; public class User { public required string PrimaryEmail { get; set; } public int UserId { get; set; } public required string Password { get; set; } public string Salt { get; set; } public required string FirstName { get; set; } public required string LastName { get; set; } public Guid? Id { get; set; } } public class CreateUser { public const int SaltByteSize = 24; public const int HashByteSize = 20; // to match the size of the PBKDF2-HMAC-SHA-1 hash public const int iterations = 1000; public User EncryptPassword(User user) { string hash; string salt; this.HashPassword(user.Password, out hash, out salt); user.Password = hash; user.Salt = salt; return user; } private void HashPassword(string password, out string hash, out string salt) { byte[] saltArray = new byte[SaltByteSize]; RandomNumberGenerator rng = RandomNumberGenerator.Create(); rng.GetBytes(saltArray); var hashArray = GetPbkdf2Bytes(password, saltArray, iterations, HashByteSize); hash = Convert.ToBase64String(hashArray); salt = Convert.ToBase64String(saltArray); } private byte[] GetPbkdf2Bytes(string password, byte[] salt, int iterations, int outputBytes) { var pbkdf2 = new Rfc2898DeriveBytes(password, salt, 10000, HashAlgorithmName.SHA512) { IterationCount = iterations }; return pbkdf2.GetBytes(outputBytes); } } class Program { public static void AddUser(User user) { string connectionString = "data source=localhost,1433;initial catalog=CSET;User Id=sa;Password=********;Encrypt=False;TrustServerCertificate=True;"; new CreateUser().EncryptPassword(user); using (SqlConnection sqlConnection = new SqlConnection(connectionString)) { try { SqlCommand sqlCommand = new SqlCommand { CommandType = CommandType.Text, CommandText = "SELECT * FROM USERS WHERE PrimaryEmail = @PrimaryEmail" }; sqlCommand.Parameters.AddWithValue("@PrimaryEmail", user.PrimaryEmail); sqlCommand.Connection = sqlConnection; sqlConnection.Open(); SqlDataReader sqlDataReader = sqlCommand.ExecuteReader(); if (sqlDataReader.Read()) { sqlDataReader.Close(); sqlCommand.CommandText = "UPDATE USERS SET Password=@Password, Salt=@Salt, FirstName=@FirstName, LastName=@LastName WHERE PrimaryEmail=@PrimaryEmail"; sqlCommand.Parameters.Clear(); sqlCommand.Parameters.AddWithValue("@Password", user.Password); sqlCommand.Parameters.AddWithValue("@Salt", user.Salt); sqlCommand.Parameters.AddWithValue("@FirstName", user.FirstName); sqlCommand.Parameters.AddWithValue("@LastName", user.LastName); sqlCommand.Parameters.AddWithValue("@PrimaryEmail", user.PrimaryEmail); sqlCommand.ExecuteNonQuery(); } else { sqlDataReader.Close(); sqlCommand.CommandText = "INSERT INTO USERS (PrimaryEmail, Password, Salt, IsSuperUser, PasswordResetRequired, FirstName, LastName, Id) VALUES (@PrimaryEmail, @Password, @Salt, 0, 0, @FirstName, @LastName, NULL)"; sqlCommand.Parameters.Clear(); sqlCommand.Parameters.AddWithValue("@PrimaryEmail", user.PrimaryEmail); sqlCommand.Parameters.AddWithValue("@Password", user.Password); sqlCommand.Parameters.AddWithValue("@Salt", user.Salt); sqlCommand.Parameters.AddWithValue("@FirstName", user.FirstName); sqlCommand.Parameters.AddWithValue("@LastName", user.LastName); sqlCommand.ExecuteNonQuery(); } sqlCommand.CommandText = "SELECT * FROM USERS WHERE PrimaryEmail = @PrimaryEmail"; sqlCommand.Parameters.Clear(); sqlCommand.Parameters.AddWithValue("@PrimaryEmail", user.PrimaryEmail); sqlDataReader = sqlCommand.ExecuteReader(); if (sqlDataReader.Read()) { int userId = (int)sqlDataReader["UserId"]; sqlDataReader.Close(); sqlCommand.CommandText = "INSERT INTO PASSWORD_HISTORY (UserId, Created, Password, Salt, Is_Temp) VALUES (@UserId, @Created, @Password, @Salt, 0)"; sqlCommand.Parameters.Clear(); sqlCommand.Parameters.AddWithValue("@UserId", userId); sqlCommand.Parameters.AddWithValue("@Created", DateTime.UtcNow); sqlCommand.Parameters.AddWithValue("@Password", user.Password); sqlCommand.Parameters.AddWithValue("@Salt", user.Salt); sqlCommand.ExecuteNonQuery(); } } catch (SqlException sqle) { throw; } } } static string ReadPassword() { StringBuilder passwordBuilder = new(); while (true) { ConsoleKeyInfo keyInfo = Console.ReadKey(intercept: true); if (keyInfo.Key == ConsoleKey.Enter){ break; } if (keyInfo.Key == ConsoleKey.Backspace) { if (passwordBuilder.Length > 0) { passwordBuilder.Remove(passwordBuilder.Length - 1, 1); Console.Write("\b \b"); } } else if (keyInfo.KeyChar != '\u0000') { passwordBuilder.Append(keyInfo.KeyChar); Console.Write("*"); } } return passwordBuilder.ToString(); } public static string getHelloWorld() { return "Hello world from here."; } static void Main(string[] args) { Console.WriteLine(getHelloWorld()); Console.Write("First name: "); var firstName = Console.ReadLine(); Console.Write("Last name: "); var lastName = Console.ReadLine(); Console.Write("Email: "); var email = Console.ReadLine(); Console.Write("Password: "); var password = ReadPassword(); Console.WriteLine(); Console.WriteLine($"{firstName} {lastName} {email} {password}"); var u = new User { FirstName = firstName, LastName = lastName, PrimaryEmail = email, Password = password }; AddUser(u); } } }}} |
cset
Cyber Security Evaluation Tool for asset owners with the primary objective of reducing the risk to the nation’s critical infrastructure.
.env
1 # CSET Web API
2 ConnectionStrings__CSET_DB="data source=mssql,1433;initial catalog=CSET;User Id=sa;Password=********;Encrypt=False;TrustServerCertificate=True;"
3
4 # Optional: URL to a custom CA certificate (for corporate proxies/VPNs)
5 # CA_CERT_URL=https://your-internal-cert-store/root_ca.crt
6
7 # Host port overrides for Docker Compose (Optional)
8 WEB_PORT=4200
9 #WEB_TLS_PORT=443
10 WEB_TLS_PORT=8443
11 API_PORT=5000
12
13 # MSSQL Server
14 MSSQL_SA_PASSWORD=********
15 ACCEPT_EULA=Y
Run compose
1 docker compose up
2
3 docker compose ps
4 NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
5 cset-api ghcr.io/cisagov/cset/api:latest "dotnet CSETWebCore.…" api 53 seconds ago Up 52 seconds 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp
6 cset-mssql mcr.microsoft.com/mssql/server:2022-CU13-ubuntu-22.04 "/opt/mssql/bin/perm…" sqlserver 53 seconds ago Up 52 seconds 0.0.0.0:1433->1433/tcp, :::1433->1433/tcp
7 cset-web ghcr.io/cisagov/cset/web:latest "/docker-entrypoint.…" web 53 seconds ago Up 52 seconds 0.0.0.0:4200->80/tcp, :::4200->80/tcp, 0.0.0.0:8443->443/tcp, :::8443->443/tcp
8
9 # http://localhost:4200/
10
11 docker compose exec sqlserver bash
12 apt update
13 apt upgrade -y
14 apt install nano vim -y
15
16 cd /opt/mssql-tools/bin/
17 ./sqlcmd
18 ./sqlcmd -S localhost -U sa -P ********
19 select name from sys.databases
20 go
21 master
22 tempdb
23 model
24 msdb
25 exit
26
27 docker compose exec sqlserver bash
28 cd /var/opt/mssql/backup/
29 cd bak-files
30 cat CSET.bak.part_a* > /tmp/CSET.bak
31 cp /var/opt/mssql/backup/restoredb.sql /tmp
32 cd /tmp
33 cp restoredb.sql restoredb.sql.ori
34 chmod 666 restoredb.sql
35 chown root restoredb.sql
36 nano restoredb.sql
37 # update to point to /tmp/CSET.bak
38 /opt/mssql-tools/bin/sqlcmd -U 'sa' -P "********" -i /tmp/restoredb.sql
After the database is restored we can access http://localhost:4200/ . We need to create a user to login.
Install dotnet 10 in debian
1 # https://dotnet.microsoft.com/en-us/download/dotnet/10.0
2 # https://learn.microsoft.com/pt-pt/dotnet/core/install/linux-debian?tabs=dotnet10
3 cd ~
4 wget https://packages.microsoft.com/config/debian/13/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
5 sudo dpkg -i packages-microsoft-prod.deb
6 rm packages-microsoft-prod.deb
7 sudo apt-get update && sudo apt-get install -y dotnet-sdk-10.0
8 dotnet --version
cset-adduser-console
Dockerfile
cset-adduser-console.csproj
1 <Project Sdk="Microsoft.NET.Sdk">
2 <PropertyGroup>
3 <OutputType>Exe</OutputType>
4 <TargetFramework>net10.0</TargetFramework>
5 <RootNamespace>cset_adduser_console</RootNamespace>
6 <ImplicitUsings>enable</ImplicitUsings>
7 <Nullable>enable</Nullable>
8 </PropertyGroup>
9 <ItemGroup>
10 <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.27" />
11 <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.1" />
12 <PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
13 <PackageReference Include="System.CommandLine" Version="2.0.8" />
14 <PackageReference Include="System.Windows.Extensions" Version="8.0.0" />
15 </ItemGroup>
16 </Project>
Program.cs
Adapted from CSETAddUser
1 using System.Text;
2 using System.Security.Cryptography;
3 using Microsoft.Data.SqlClient;
4 using System.Data;
5
6 public class User {
7 public required string PrimaryEmail { get; set; }
8 public int UserId { get; set; }
9 public required string Password { get; set; }
10 public string Salt { get; set; }
11 public required string FirstName { get; set; }
12 public required string LastName { get; set; }
13 public Guid? Id { get; set; }
14 }
15
16 public class CreateUser {
17 public const int SaltByteSize = 24;
18 public const int HashByteSize = 20; // to match the size of the PBKDF2-HMAC-SHA-1 hash
19 public const int iterations = 1000;
20 public User EncryptPassword(User user) {
21 string hash;
22 string salt;
23 this.HashPassword(user.Password, out hash, out salt);
24 user.Password = hash;
25 user.Salt = salt;
26 return user;
27 }
28
29 private void HashPassword(string password, out string hash, out string salt) {
30 byte[] saltArray = new byte[SaltByteSize];
31 RandomNumberGenerator rng = RandomNumberGenerator.Create();
32 rng.GetBytes(saltArray);
33 var hashArray = GetPbkdf2Bytes(password, saltArray, iterations, HashByteSize);
34 hash = Convert.ToBase64String(hashArray);
35 salt = Convert.ToBase64String(saltArray);
36 }
37
38 private byte[] GetPbkdf2Bytes(string password, byte[] salt, int iterations, int outputBytes) {
39 var pbkdf2 = new Rfc2898DeriveBytes(password, salt, 10000, HashAlgorithmName.SHA512) {
40 IterationCount = iterations
41 };
42 return pbkdf2.GetBytes(outputBytes);
43 }
44 }
45
46 class Program {
47 public static void AddUser(User user) {
48 string connectionString = "data source=localhost,1433;initial catalog=CSET;User Id=sa;Password=********;Encrypt=False;TrustServerCertificate=True;";
49
50 new CreateUser().EncryptPassword(user);
51
52 using (SqlConnection sqlConnection = new SqlConnection(connectionString)) {
53 try {
54 SqlCommand sqlCommand = new SqlCommand {
55 CommandType = CommandType.Text,
56 CommandText = "SELECT * FROM USERS WHERE PrimaryEmail = @PrimaryEmail"
57 };
58 sqlCommand.Parameters.AddWithValue("@PrimaryEmail", user.PrimaryEmail);
59 sqlCommand.Connection = sqlConnection;
60 sqlConnection.Open();
61 SqlDataReader sqlDataReader = sqlCommand.ExecuteReader();
62
63 if (sqlDataReader.Read()) {
64 sqlDataReader.Close();
65 sqlCommand.CommandText = "UPDATE USERS SET Password=@Password, Salt=@Salt, FirstName=@FirstName, LastName=@LastName WHERE PrimaryEmail=@PrimaryEmail";
66 sqlCommand.Parameters.Clear();
67 sqlCommand.Parameters.AddWithValue("@Password", user.Password);
68 sqlCommand.Parameters.AddWithValue("@Salt", user.Salt);
69 sqlCommand.Parameters.AddWithValue("@FirstName", user.FirstName);
70 sqlCommand.Parameters.AddWithValue("@LastName", user.LastName);
71 sqlCommand.Parameters.AddWithValue("@PrimaryEmail", user.PrimaryEmail);
72 sqlCommand.ExecuteNonQuery();
73 }
74 else {
75 sqlDataReader.Close();
76 sqlCommand.CommandText = "INSERT INTO USERS (PrimaryEmail, Password, Salt, IsSuperUser, PasswordResetRequired, FirstName, LastName, Id) VALUES (@PrimaryEmail, @Password, @Salt, 0, 0, @FirstName, @LastName, NULL)";
77 sqlCommand.Parameters.Clear();
78 sqlCommand.Parameters.AddWithValue("@PrimaryEmail", user.PrimaryEmail);
79 sqlCommand.Parameters.AddWithValue("@Password", user.Password);
80 sqlCommand.Parameters.AddWithValue("@Salt", user.Salt);
81 sqlCommand.Parameters.AddWithValue("@FirstName", user.FirstName);
82 sqlCommand.Parameters.AddWithValue("@LastName", user.LastName);
83 sqlCommand.ExecuteNonQuery();
84 }
85
86 sqlCommand.CommandText = "SELECT * FROM USERS WHERE PrimaryEmail = @PrimaryEmail";
87 sqlCommand.Parameters.Clear();
88 sqlCommand.Parameters.AddWithValue("@PrimaryEmail", user.PrimaryEmail);
89 sqlDataReader = sqlCommand.ExecuteReader();
90 if (sqlDataReader.Read()) {
91 int userId = (int)sqlDataReader["UserId"];
92 sqlDataReader.Close();
93 sqlCommand.CommandText = "INSERT INTO PASSWORD_HISTORY (UserId, Created, Password, Salt, Is_Temp) VALUES (@UserId, @Created, @Password, @Salt, 0)";
94 sqlCommand.Parameters.Clear();
95 sqlCommand.Parameters.AddWithValue("@UserId", userId);
96 sqlCommand.Parameters.AddWithValue("@Created", DateTime.UtcNow);
97 sqlCommand.Parameters.AddWithValue("@Password", user.Password);
98 sqlCommand.Parameters.AddWithValue("@Salt", user.Salt);
99 sqlCommand.ExecuteNonQuery();
100 }
101 }
102 catch (SqlException sqle) {
103 throw;
104 }
105 }
106 }
107
108 static string ReadPassword() {
109 StringBuilder passwordBuilder = new();
110 while (true) {
111 ConsoleKeyInfo keyInfo = Console.ReadKey(intercept: true);
112
113 if (keyInfo.Key == ConsoleKey.Enter){
114 break;
115 }
116
117 if (keyInfo.Key == ConsoleKey.Backspace) {
118 if (passwordBuilder.Length > 0) {
119 passwordBuilder.Remove(passwordBuilder.Length - 1, 1);
120 Console.Write("\b \b");
121 }
122 }
123 else if (keyInfo.KeyChar != '\u0000') {
124 passwordBuilder.Append(keyInfo.KeyChar);
125 Console.Write("*");
126 }
127 }
128 return passwordBuilder.ToString();
129 }
130
131 public static string getHelloWorld() {
132 return "Hello world from here.";
133 }
134
135 static void Main(string[] args) {
136 Console.WriteLine(getHelloWorld());
137 Console.Write("First name: ");
138 var firstName = Console.ReadLine();
139 Console.Write("Last name: ");
140 var lastName = Console.ReadLine();
141 Console.Write("Email: ");
142 var email = Console.ReadLine();
143 Console.Write("Password: ");
144 var password = ReadPassword();
145 Console.WriteLine();
146 Console.WriteLine($"{firstName} {lastName} {email} {password}");
147
148 var u = new User {
149 FirstName = firstName,
150 LastName = lastName,
151 PrimaryEmail = email,
152 Password = password
153 };
154 AddUser(u);
155 }
156 }
