ACECTF
WEB
Buried Deep
"I’m not a hacker. I’m just someone who wants to make the world a little better. But the world isn’t going to change itself."
Submit your answer in the following format: ACECTF{3x4mpl3_fl4g}
The flag content should be in lowercase letters only.
http://34.131.133.224:9998/
/robots.txtにアクセスしてみるとヒットする
Hey there, you're not a robot, yet I see you sniffing through this file 😡
Now get off my lawn! 🚫
Disallow: /secret/
Disallow: /hidden/
Disallow: /cryptic/
Disallow: /forbidden/
Disallow: /pvt/
Disallow: /buried/
Disallow: /underground/
Disallow: /secret_path/
Disallow: /hidden_flag/
Disallow: /buried_flag/
Disallow: /encrypted/
/buriedにアクセスすると
49 115 116 32 80 97 114 116 32 111 102 32 116 104 101 32 70 108 97 103 32 105 115 32 58 32 65 67 69 67 84 70 123 49 110 102 49 108 55 114 52 55 49 110 103 95 55 104 51 95 53 121 53 55 51 109 95 32
が表示される
ASCIIコード直すと1st Part of the Flag is : ACECTF{1nf1l7r471ng_7h3_5y573m_
となる
次に
/secret_pathにアクセスするとモールス信号がある
..--- -. -..
.--. .- .-. -
--- ..-.
- .... .
..-. .-.. .- --.
.. ...
---...
.---- ..... ..--.- ...-- ....- ..... -.-- ..--.- .-- .... ...-- -. ..--.- -.-- ----- ..- ..--.- -.- -. ----- .-- ..--.- .-- .... ...-- .-. ...-- ..--.-
変換すると2ND PART OF THE FLAG IS: 15_345Y_WH3N_Y0U_KN0W_WH3R3_
bC5 !2CE @7 E96 u=28 :D i f9b0db4CbEd0cCb03FC`b5N
で識別するとROT47だったので変換する
3rd Part of the Flag is : 7h3_53cr3t5_4r3_bur13d}
全て組み合わせると完成
AECTF{1nf1l7r471ng_7h3_5y573m_15_345y_wh3n_y0u_kn0w_wh3r3_7h3_53cr3t5_4r3_bur13d}
Webrypto
I think we can all agree that most of us grew up watching the iconic cartoon Tom & Jerry. Every kid would feel that surge of adrenaline during the thrilling chases and chaotic conflicts between the mischievous mouse and the ever-determined cat. The excitement of those scenes—the heart-pounding moments of escape—sometimes felt almost real.
But then, I heard a little rumor: what if all those chases were fake? What if Tom and Jerry were actually friends all along? That revelation shook me. I had no one to ask about this mind-bending twist, so I decided to take matters into my own hands—I created a web app to settle this question once and for all.
I know the truth now. Do you think you can uncover it too?
https://chal.acectf.tech/Webrypto/
- tomとjerryが同じ値でないことを確認
- 連結された文字列
'ACECTF' . $_GET['tom'] と 'ACECTF' . $_GET['jerry']
のMD5ハッシュが一致するかを確認
配列を渡すと、PHPはGETパラメータを配列として解釈される
$_GET['tom'] と $_GET['jerry']
が比較される際、配列同士の比較は行われず、それぞれの配列内の値が比較されることになるので以下のクエリパラメータを含めてアクセスしてみる
https://chal.acectf.tech/Webrypto/?tom[]=a&jerry[]=b
アクセスすると
ACECTF{70m_4nd_j3rry_4r3_4ll135}
Flag-Fetcher
Hey guys, I created a flag fetcher using some web stacks & technologies. It was supposed to fetch the flag.webp image file which contains the flag but there was some kind of error in doing that. Can you verify it? Maybe just get the flag I don't really care if you fix it or not.
This should've worked
acectf{r3d1r3ct10n}
Forensic
Broken Secrets
You’ve found a suspicious file, but it seems broken and cannot be opened normally. Your goal is to uncover its secrets.
Submit your answer in the following format: ACECTF{3x4mpl3_fl4g}
7-zipだとわかったので解凍して、中見るとnot_so_suspicious_fileというのもを見つけた
~/ctf/ace-ctf/forensic$ file Brokenfr
Brokenfr: 7-zip archive data, version 0.4
~/ctf/ace-ctf/forensic$ 7z l Brokenfr
7-Zip 23.01 (x64) : Copyright (c) 1999-2023 Igor Pavlov : 2023-06-20
64-bit locale=C.UTF-8 Threads:12 OPEN_MAX:1024
Scanning the drive for archives:
1 file, 10240 bytes (10 KiB)
Listing archive: Brokenfr
--
Path = Brokenfr
Type = 7z
Physical Size = 10240
Headers Size = 451
Method = LZMA2:96k
Solid = +
Blocks = 1
Date Time Attr Size Compressed Name
------------------- ----- ------------ ------------ ------------------------
2025-01-20 00:38:03 D.... 0 0 _
2025-01-20 00:38:03 D.... 0 0 _/docProps
2025-01-20 00:38:03 D.... 0 0 _/word
2025-01-20 00:49:37 D.... 0 0 _/word/media
2025-01-20 00:38:03 D.... 0 0 _/word/theme
2025-01-20 00:38:03 D.... 0 0 _/word/_rels
2025-01-20 00:38:03 D.... 0 0 _/_rels
1980-01-01 03:30:00 ..... 709 9789 _/docProps/app.xml
1980-01-01 03:30:00 ..... 759 _/docProps/core.xml
1980-01-01 03:30:00 ..... 4010 _/word/document.xml
1980-01-01 03:30:00 ..... 1833 _/word/fontTable.xml
2025-01-20 00:48:23 ....A 3209 _/word/media/not_so_suspicious_file
1980-01-01 03:30:00 ..... 3330 _/word/settings.xml
1980-01-01 03:30:00 ..... 42760 _/word/styles.xml
1980-01-01 03:30:00 ..... 8399 _/word/theme/theme1.xml
1980-01-01 03:30:00 ..... 1069 _/word/webSettings.xml
1980-01-01 03:30:00 ..... 949 _/word/_rels/document.xml.rels
1980-01-01 03:30:00 ..... 1362 _/[Content_Types].xml
1980-01-01 03:30:00 ..... 590 _/_rels/.rels
------------------- ----- ------------ ------------ ------------------------
2025-01-20 00:49:37 68979 9789 12 files, 7 folders
破損しているようなので、PNGファイルの正しいヘッダーに直す
#16進数
89 50 4E 47 0D 0A 1A 0A
.png拡張子つけて保存し、開いてみるとflagが出てきた
ACETF{h34d3r_15_k3y}
Virtual Hard Disk
One of the first things I learnt when I started learning to hack was linux. It was fun until I hit a ceiling of understanding about the differences in Operating Systems, what's a Shell, Kernel, etc.
But once I got better I started developing a liking towards the terminal and how the Linux operating system isbetter
than say Windows, orworse
in some cases. How none of them is superior, nor the other inferior. We shall find out with this challenge.
Be careful, a lot of fake galfs around.
challenge
┌──(kali㉿kali)-[/media/sf_vm_share/ctf/ace-ctf/forensic]
└─$ file challenge
challenge: DOS/MBR boot sector MS-MBR Windows 7 english at offset 0x163 "Invalid partition table" at offset 0x17b "Error loading operating system" at offset 0x19a "Missing operating system"; partition 1 : ID=0xee, start-CHS (0x0,0,2), end-CHS (0xb,254,63), startsector 1, 4294967295 sectors
どうやらブートセクターです
MBR(Master Boot Record)とは、ハードディスクなどのストレージ(外部記憶装置)の最も先頭にある、起動に必要なプログラムや情報を記録した小さな領域
コンピュータの起動時に実行される小さなプログラムで、オペレーティングシステム(OS)のブートローダーの場所を特定し、コンピュータを起動できるようにする
FTKImagerで開いて眺めてみるとflagとkeyのファイルを見つけた
ヴィジュネル暗号だと思い復号すると正しいflagになった
ACECTF{7h3_d1ff3r3nc3_b37w33n_y0u_4nd_m3}
OSINT
The Mysterious Building
Wow, that's a cool tower—I remember it well; saw it when I was on the metro one fine evening. But the building on the right... Something about its logo looks familiar, but I just can’t recall its name. Can you help me figure out the name of this mysterious building?
Flag format - ACECTF{building_name}. All lowercase, seperated by underscores instead of spaces. E.g. - ACECTF{white_house}
exiftool使う
┌──(kali㉿kali)-[/media/sf_vm_share/ctf/ace-ctf]
└─$ exiftool OSINT-1.jpg
ExifTool Version Number : 12.76
File Name : OSINT-1.jpg
Directory : .
File Size : 255 kB
File Modification Date/Time : 2025:02:27 16:38:01+09:00
File Access Date/Time : 2025:03:01 00:41:26+09:00
File Inode Change Date/Time : 2025:03:01 00:39:02+09:00
File Permissions : -rwxrwx---
File Type : JPEG
File Type Extension : jpg
MIME Type : image/jpeg
JFIF Version : 1.01
Resolution Unit : inches
X Resolution : 96
Y Resolution : 96
XMP Toolkit : Image::ExifTool 13.10
Description : National Capital of India
Author : Описание соответствует действительности
Comment : Определенно не Россия
Image Width : 734
Image Height : 858
Encoding Process : Baseline DCT, Huffman coding
Bits Per Sample : 8
Color Components : 3
Y Cb Cr Sub Sampling : YCbCr4:2:0 (2 2)
Image Size : 734x858
Megapixels : 0.630
National Capital of Indiaについて調べると、Delhが出てくる
何個かのサイトで写真から場所検索してみると、
Pitampura TV Towerと書かれている、検索してみると同じタワーだった
しかしgoogleMapとストリートビューをずっと見ててもなかなか見つからなくて苦戦
検索しまくってhttps://www.youtube.com/watch?v=PVWj6LvZjLk
youtubeで動画を発見1:47らへんに似た建物がある
PP Trade Centerで検索すると同じロゴの建物だった
ACECTF{PP_Trade_Center}
Stegano
Cryptic Pixels
This image looks normal at first, but something important is hidden inside. The secret is carefully concealed, making it hard to find.
Your task is to explore the image, uncover the hidden message, and reveal what’s concealed. Do you have what it takes to crack the code and unlock the secret?
Submit your answer in the following format: ACECTF{3x4mpl3_fl4g}
CrypticPixels.png
binwalk -e CryticPixels.png
するとB8103.zipが手に入るが、パスワードがわからないのでzip2johnで辞書攻撃する
┌──(kali㉿kali)-[/media/sf_vm_share/ctf/ace-ctf/steg]
└─$ zip2john ./_CrypticPixels.png.extracted/B8103.zip > zip_hash.txt
ver 1.0 efh 5455 efh 7875 B8103.zip/flag.txt PKZIP Encr: 2b chk, TS_chk, cmplen=38, decmplen=26, crc=49DE1393 ts=1897 cs=1897 type=0
┌──(kali㉿kali)-[/media/sf_vm_share/ctf/ace-ctf/steg]
└─$ ls
CrypticPixels.png _CrypticPixels.png.extracted HeaderHijack.zip Tabsspaces.zip WhisperingWaves.zip zip_hash.txt
┌──(kali㉿kali)-[/media/sf_vm_share/ctf/ace-ctf/steg]
└─$ john zip_hash.txt
Using default input encoding: UTF-8
Loaded 1 password hash (PKZIP [32/64])
Will run 2 OpenMP threads
Proceeding with single, rules:Single
Press 'q' or Ctrl-C to abort, almost any other key for status
Almost done: Processing the remaining buffered candidate passwords, if any.
Proceeding with wordlist:/usr/share/john/password.lst
qwertyuiop (B8103.zip/flag.txt)
1g 0:00:00:00 DONE 2/3 (2025-02-27 17:25) 7.142g/s 454628p/s 454628c/s 454628C/s 123456..Peter
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
qwertyuiopがパスワードと分かったのでこれを使う。flag.txtの中のflagをROT13すると正しいflagが手に入る
ACECTF{h4h4_y0u'r3_5m4r7}
HeaderHijack
A secret agent's intercepted video file refuses to play. A mysterious checksum file was found alongside it. Your task is to repair the file and retrieve the flag...
┌──(kali㉿kali)-[/media/sf_vm_share/ctf/ace-ctf/steg]
└─$ file not_the_flag.mp4
not_the_flag.mp4: data
mp4修復サイト、で検索して見つけた以下のサイトにアップロードする
修復された動画を再生すると、0:04秒の時にflagが現れた
ACECTF{d3c0d3_h3x_1s_fun}
Crypto
Super Secure Encryption
I'm doing a big favour with this one... I'm handing out my super secure functionality to the outer world to stumble upon & explore. Though, I still remember one of my colleagues once saying that nothing in this world is secure nowadays but my script right here stands on the contrary. I'll give you the access to my arsenal and see if you can prove me wrong.
from Crypto.Cipher import AES
from Crypto.Util import Counter
import os
k = os.urandom(16) # Is it too short?
def encrypt(plaintext):
cipher = AES.new(k, AES.MODE_CTR, counter=Counter.new(128)) # I was told, CTR can't be broken!
ciphertext = cipher.encrypt(plaintext)
return ciphertext.hex()
msg = b'This is just a test message and can totally be ignored.' # Just checking functionality
encrypted_msg = encrypt(msg)
with open('flag.txt', 'r') as f:
flag = f.readline().strip().encode()
encrypted_flag = encrypt(flag)
with open('msg.txt', 'w+') as o:
o.write(f"{encrypted_msg}\n")
o.write(f"{encrypted_flag}")
d71f4a2fd1f9362c21ad33c7735251d0a671185a1b90ecba27713d350611eb8179ec67ca7052aa8bad60466b83041e6c02dbfee738c2a3
c234661fa5d63e627bef28823d052e95f65d59491580edfa1927364a5017be9445fa39986859a3
ソースコードとtxtが与えられる
CTRモードは同じカウンター値で同じ鍵を使うと、暗号文が危険になる脆弱性がある
- 同じカウンターと鍵の使用: 上記のコードでは、同じカウンターと鍵が使用されています。これにより、同じ鍵ストリームが生成されるため、異なるメッセージが同じ場所で同じXOR操作を受ける
-
既知の平文を利用:
msg = b'This is just a test message and can totally be ignored.'
という既知の平文が暗号化されているので、その暗号文と比較し、鍵ストリームを復号できる
#solve.py
from Crypto.Cipher import AES
from Crypto.Util import Counter
import binascii
known_plaintext = b'This is just a test message and can totally be ignored.'
ciphertext_hex = 'd71f4a2fd1f9362c21ad33c7735251d0a671185a1b90ecba27713d350611eb8179ec67ca7052aa8bad60466b83041e6c02dbfee738c2a3'
ciphertext = binascii.unhexlify(ciphertext_hex)
# 鍵ストリームを復号
keystream = bytes([ct ^ pt for ct, pt in zip(ciphertext, known_plaintext)])
# フラグの暗号文を復号
flag_ciphertext_hex = 'c234661fa5d63e627bef28823d052e95f65d59491580edfa1927364a5017be9445fa39986859a3'
flag_ciphertext = binascii.unhexlify(flag_ciphertext_hex)
flag = bytes([fc ^ ks for fc, ks in zip(flag_ciphertext, keystream)])
print(f"The flag is: {flag.decode()}")
~/ctf/ace-ctf/cry$ python3 solve.py
The flag is: ACECTF{n07h1n6_15_53cur3_1n_7h15_w0rld}
ACECTF{n07h1n6_15_53cur3_1n_7h15_w0rld}
A Little Extra Knowledge Is Too Dangerous
Have you ever heard the quotes, A little knowledge is a dangerous thing and In the land of the blind, the one-eyed man is king? They strike me as deeply contradictory—one condemning the slightly knowledgeable, while the other exalts them.
This contradiction highlights something unsettling: fairness doesn’t seem to exist in this world. Everyone seems to twist things to suit their own agendas, leading to divisions—arbitrary ones—where people impose their ideologies on others.
What if we eliminated excess knowledge and these divisions altogether? Perhaps then we could live like illiterate cynics—but in peace.
That’s the essence of this challenge I’m presenting to you. Or should I call it a sermon?
chal.txt
QUNFQ1RGe/==MV82dTM1NV95MHVfN3J1bmM0N/===zNkXzdoM18zeDdyNF9rbjB3bDNkNjNfcjRkMG1fNTdyMW42NjY2NjY2NjY2NjU1NTU1NTU1NV94eHh4eHh4YmJieHh4eHh4Y2NjY3h9
base64で==
つけたり外してみたりするとできた
ACECTF{1_6u355_y0u_7runc473d_7h3_3x7r4_kn0wl3d63_r4d0m_57r1n66666666666555555555_xxxxxxxbbbxxxxxxccccx}
Binary
!Underflow
Something simple to warm you up.
$ strings exploit-me | grep {
ACECTF{buff3r_0v3rfl3w}
ACECTF{buff3r_0v3rfl3w}
Rev
The Chemistry Of Code
During a discussion with hackers, one idea stuck: every hacker must be able to understand code, no matter how cryptic.
Hidden within obfuscated Rust code is a function that holds the flag. But it only unlocks when you reverse its logic and uncover the correct username and password.
Do you have what it takes to decode this tangled masterpiece? Dive into the chemistry of code and prove your skills.
Hint: Some secrets are worth their salt.
chemistryofcode.zip
Rustが与えられる
┌──(kali㉿kali)-[/media/…/ace-ctf/rev/chemistryofcode/src]
└─$ cat main.rs
use base64::{engine::general_purpose::STANDARD, Engine};
use hex::encode as hex_encode;
use num_bigint::BigUint;
use std::io::{self, Write};
const FERROUS_OXIDE_USERNAME: &str = "AdminFeroxide";
const ANIONIC_PASSWORD: &str = "NjQzMzcyNzUzNTM3MzE2Njc5MzE2ZTM2";
const ALKALINE_SECRET: &str = "4143454354467B34707072336E373163335F3634322C28010D3461302C392E";
fn ionic_bond(cation_input: &str, anion_input: &str) {
let cation_hex = hex_encode(cation_input);
let anion_hex = hex_encode(anion_input);
let cation_value = BigUint::parse_bytes(cation_hex.as_bytes(), 16).unwrap();
let anion_value = BigUint::parse_bytes(anion_hex.as_bytes(), 16).unwrap();
let covalent_link = &cation_value ^ &anion_value;
let alkaline_secret_value = BigUint::parse_bytes(ALKALINE_SECRET.as_bytes(), 16).unwrap();
let metallic_alloy = &covalent_link ^ &alkaline_secret_value;
let precipitate = format!("{:x}", metallic_alloy);
let alloy_compound = (0..precipitate.len())
.step_by(2)
.map(|i| u8::from_str_radix(&precipitate[i..i + 2], 16).unwrap() as char)
.collect::<String>();
println!("Crystallized Flag (ASCII): {}", alloy_compound);
}
fn reaction_chamber() {
let mut username = String::new();
print!("Introduce the Catalyst: ");
io::stdout().flush().unwrap();
io::stdin().read_line(&mut username).unwrap();
let username = username.trim();
let mut password = String::new();
print!("Introduce the Reagent: ");
io::stdout().flush().unwrap();
io::stdin().read_line(&mut password).unwrap();
let password = password.trim();
if username != FERROUS_OXIDE_USERNAME {
println!("Reaction denied: Unstable molecule detected.");
return;
}
let reagent_ion = STANDARD.encode(hex_encode(password).as_bytes());
if reagent_ion != ANIONIC_PASSWORD {
println!("Reaction denied: Unstable molecule detected.");
return;
}
ionic_bond(username, password);
}
fn main() {
reaction_chamber();
}
username: AdminFeroxide
pass: NjQzMzcyNzUzNTM3MzE2Njc5MzE2ZTM2
と書かれている
base64とHexで復号するとd3ru571fy1n6
AdminFeroxide
とd3ru571fy1n6
使ってRustを実行する
~/ctf/ace-ctf/rev/chemistryofcode/src$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.08s
Running `/home/iniad/ctf/ace-ctf/rev/chemistryofcode/target/debug/chemistryofcode`
Introduce the Catalyst: AdminFeroxide
Introduce the Reagent: d3ru571fy1n6
Crystallized Flag (ASCII): ACECTF{4ppr3n71c3_w4l73r_wh1t3}
ACECTF{4ppr3n71c3_w4l73r_wh1t3}
DONOTOPEN
A suspicious script file seems to be hiding something important, but it refuses to cooperate. It's obfuscated, tampered with, and demands a password. Unravel the mystery to uncover the hidden flag.
DONTOPEN
┌──(kali㉿kali)-[/media/sf_vm_share/ctf/ace-ctf/rev]
└─$ binwalk -e DONTOPEN
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
693 0x2B5 gzip compressed data, has original file name: "pythonscript.py", from Unix, last modified: 2025-01-25 14:43:44
WARNING: One or more files failed to extract: either no utility was found or it's unimplemented
pythonscript.pyが手に入ったのでcatで見てみる
┌──(kali㉿kali)-[/media/sf_vm_share/ctf/ace-ctf/rev]
└─$ cat _DONTOPEN.extracted/pythonscript.py
import hashlib
import requests
import webbrowser
NOT_THE_FLAG = "flag{this-is-not-the-droid-youre-looking-for}"
flag0 = 'flag{cfcd208495d565ef66e7dff9f98764da}'
flag1 = 'flag{c4ca4238a0b923820dcc509a6f75849b}'
...
flag998 = 'flag{9ab0d88431732957a618d4a469a0d4c3}'
flag999 = 'flag{b706835de79a2b4e80506f582af3676a}'
FLAG_PREFIX = "ACE{%s}"
print("It looks like the box is locked with some kind of password, determine the pin to open the box!")
req = requests.get("http://google.com")
req.raise_for_status()
pin = input("What is the pin code?")
if pin == "ACE@SE7EN":
print("Looks good to me...")
print("I guess I'll generate a flag")
req = requests.get("http://example.com")
req.raise_for_status()
print(FLAG_PREFIX % hashlib.blake2b((pin + "Vansh").encode("utf-8")).hexdigest()[:32])
else:
print("Bad pin!")
binwalkから抽出したpythonコードから、pin == "ACE@SE7EN”を入力するのがわかる
実行するとWhat is the pin code?
と求められるのでACE@SE7EN
を入れるとflagが手に入る
~/ctf/ace-ctf/rev$ python3 pythonscript.py
It looks like the box is locked with some kind of password, determine the pin to open the box!
gio: https://vipsace.org/: Operation not supported
What is the pin code?ACE@SE7EN
Looks good to me...
I guess I'll generate a flag
ACE{e2e3619b630b3be9de762910fd58dba7}
ACE{e2e3619b630b3be9de762910fd58dba7}