# TeamCity Setup

### Module Objectives

* Setup TeamCity
* Install Languages
  * C#
  * Go
* Create Users
* Configure GitLab to work with TeamCity

### Prerequisites

{% code overflow="wrap" %}

```yaml
Minimum:
- 4GB RAM
- 64GB Disk Space
- Virtualisation Software (VMWare or VirtualBox)
- Windows 10 Pro
- Git
- Java JDK 17 / 22
```

{% endcode %}

### Installing TeamCity

{% hint style="info" %}
**Section Objectives**

* Install the TeamCity Server
* Install the TeamCity Agent
* Exclude the TeamCity folder from Defender
  {% endhint %}

Compiling .NET Framework projects is easier on a Windows machine, hence we will be installing TeamCity on a Windows virtual machine. You can download TeamCity Professional from [here](https://www.jetbrains.com/teamcity/download/).

Configure your install directory (or leave it as the default), and copy the path down. Since we will be compiling malicious projects, we must add a Defender exclusion to this path. You can leave everything as default.

<figure><img src="/files/D3UbXPhZru4S8hfMYGEW" alt=""><figcaption><p>Make sure to have all of these selected</p></figcaption></figure>

TeamCity supports multiple build agents, which can be used in conjunction with GitLab's build agents as part of a CI/CD cycle (***GitLab Repo -> TeamCity Compilation -> File Sharing Server***)

Once installation is complete, you should see the build agent properties pop up. Note down the server address.

<figure><img src="/files/oVEuG1WMjPiTlOdlpNU2" alt=""><figcaption><p>Build Agent Properties</p></figcaption></figure>

Save the properties, then you can select whether you'd like it to run as a domain/local user, or as SYSTEM. We will run the server and the build agent as the SYSTEM account for simplicity's sake.

<figure><img src="/files/MVQaQ8uaztOkIZtYOSts" alt=""><figcaption><p>Running as SYSTEM</p></figcaption></figure>

Once done, open the UI at `http://<TEAM_CITY_ADDRESS>:8111.` Select the internal database (or set up an external one for long-term storage - [see migration steps here](https://www.jetbrains.com/help/teamcity/2024.03/migrating-to-external-database.html?Migrating+to+an+External+Database#Switch+with+No+Data+Migration) if you are following along), proceed, then accept the license agreement, and deselect the anonymous stats submission.

<figure><img src="/files/IA50sFC2wTwJirZ5UthR" alt=""><figcaption><p>Database Type</p></figcaption></figure>

<figure><img src="/files/qtxXqRjce5XjfgPPqW82" alt=""><figcaption><p>License Agreement</p></figcaption></figure>

Once this is done, create an admin account then move on to the next section.

<figure><img src="/files/As3cUOgRqnfPxE2gBle4" alt=""><figcaption><p>TeamCity Dashboard</p></figcaption></figure>

#### Defender Settings

As mentioned before, we need to add an exclusion to Defender to prevent it from deleting our artifacts. Open Defender, then click on Manage settings

<figure><img src="/files/QGrIXsCYcpzyO6zwcoxa" alt=""><figcaption><p>Defender dashboard</p></figcaption></figure>

Turn off automatic sample submission to stop our artifacts from getting burned, then scroll down, click on add or remove exclusions, and add the TeamCity directory. The default location is `C:\Teamcity`

<figure><img src="/files/7uSCBSHNQawU58NZQ4tC" alt=""><figcaption><p>Auto sample submission and exclusions</p></figcaption></figure>

<figure><img src="/files/B7S9D4n6h7mLkwXVMbih" alt=""><figcaption><p>After adding an exclusion</p></figcaption></figure>

### Install Programming Languages

#### Git

Since we will clone GitHub repositories, [Git](https://git-scm.com/download/win) is required on the TeamCity server.

#### C\#

To compile most of the C#-based tools that we will be using in this blog, we need the .NET 4.0 and 4.5 targeting packs, as well as the 3.5 development tools. Since these are considered deprecated, they were removed from [dotnet.microsoft.com](https://dotnet.microsoft.com). A workaround is installing [Visual Studio 2019](https://learn.microsoft.com/en-us/visualstudio/releases/2019/release-notes-preview), then downloading the .NET Desktop Workload and targeting packs.

<figure><img src="/files/FPCJPqNDqV3bhJjQdste" alt=""><figcaption><p>Installing .NET Desktop Development</p></figcaption></figure>

<figure><img src="/files/VLdsZUENUNK1pEQfxI0X" alt=""><figcaption><p>Double check the components and add 3.5 development tools</p></figcaption></figure>

#### Golang

Installing Golang is pretty simple, you can get it from [their website](https://go.dev/doc/install), download the installer, and then hit next for everything

### Configuring GitLab (Optional)

#### Integration

If you would like to use TeamCity as part of your CI/CD pipeline, you can add it from the integrations section on GitLab at ***Admin -> Integrations -> JetBrains TeamCity***

<figure><img src="/files/JUpp8MXJzapVkrkAlBkZ" alt=""><figcaption><p>TeamCity integration config</p></figcaption></figure>

You will need to change the `http://localhost:8111` default server URL to one that is accessible to GitLab (NAT/Host-Only for example)

<figure><img src="/files/BCdFtHJH6mSc6A7y6JyB" alt=""><figcaption><p>Change the server URL</p></figcaption></figure>

#### SSH Key(s)

Since we might have a mixture of private and public repositories on GitLab, we need to create an SSH key on our Windows server, then copy the public key to our ***GitLab server -> Deployment Keys -> New deploy keys***

1. **Windows Server**

<figure><img src="/files/emQiNYbfmDPiND6TVeJ5" alt=""><figcaption><p>Creating an SSH Key</p></figcaption></figure>

```powershell
> ssh-keygen
> cat ~/.ssh/ssh_key_name.pub
```

2. **GitLab Server**

{% hint style="info" %}
Alternatively, you can add deploy keys per project instead of instance-wide to reduce your attack surface.
{% endhint %}

<figure><img src="/files/9e9oA26X1m3DQkn12wLM" alt=""><figcaption><p>Deploy Key Dashboard</p></figcaption></figure>

<figure><img src="/files/4ldDe82tpcWTMSXhyq5H" alt=""><figcaption><p>Adding our newly created SSH public key</p></figcaption></figure>

Create a new key and add one on the user you want to access repositories from

<figure><img src="/files/CxDUdZDKgEWmBzHlCX5w" alt=""><figcaption><p>SSH Pubkey on user</p></figcaption></figure>

#### Personal Access Token(s)

Another way of doing this is by using Personal Access Tokens. These are unique random characters that allows for authentication through the GUI, as well as through REST APIs - which will come in handy if you make a builder tool later on for individual operators.

To add them, go to ***Edit Profile -> Access Tokens -> Add new token***

<figure><img src="/files/0a7c4rA1PIhipZreZjN3" alt=""><figcaption><p>Create Token - 1</p></figcaption></figure>

Give the token a name, and check the permissions that you want it to have, then create the token.

<figure><img src="/files/zPL1qfH5ORb133KLkj7e" alt=""><figcaption><p>Creating a TeamCity token</p></figcaption></figure>

Save the token in a secure location (Such as Bitwarden's Secrets Manager) so you can re-use it later on.

<figure><img src="/files/5ssk01rb5J0XK3qseEfo" alt=""><figcaption><p>Created Token</p></figcaption></figure>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://blog.securescape.cc/offensive-security/red-team/offensive-development/offensive-devops/teamcity/teamcity-setup.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
