flagyard web-NOSJ
Welcome to our E-commerce website, I wish you enjoy the journey.
- First Man StandingHi everyone this challenge stayed unsolved for a long time so in this writeup I’ll walk through the full idea i Hope you enjoy ; )
The application exposes two roles:
Buyer == needs a valid invitation code to open the store and receive the flag
Seller == can generate buyer invitation codesSo first we must register a seller, then use seller to invite the buyer
When you register as Buyer
you gonna need Invitation
So let’s register as seller to inv the buyer
And here is the first trick which is we need active the seller
but When you check your req
The trick is the activated only accepts a boolean (true/false) and you can’t set it to true
we can bybass this by duplicate keys using Unicode truncation:
Now the seller account becomes active and you can access the seller dashboard
let’s inv our Buyer account
Back to burp to see the req
ok now we have the inv code
Invitation submitted! The invitation is still new and upcoming, we’ll contact you once this store is open.
So until now the idea is clear we just need tp open the store by find inv code open it for us
moving into the next step
The endpoint /get_buyer_invitation accepts a list of names. When the list contains repeated values, the response returns a list of sequential invitation codes (one per element)
so i used
{"name": [NaN, NaN, NaN,
NaN, NaN, NaN,]} To dump all codes
Get Dr.kasbr’s stories in your inbox
Join Medium for free to get updates from this writer.
Soo the idea now is trying all these codes and see if anything gonna happen
but yah nothing worked i even checked the formatting/lengt for every code but it’s wan’t the same every code have random number
However, after restarting the instance multiple times and re-dumping, a clear structure appeared:
- There are always 800 codes
- The codes are sequential and deterministic for the instance
- The code values are in the 0..2^32-1 range
- no values outside unsigned 32‑bit range That lines up strongly with a PRNG-backed generation mechanism rather than “real randomness”.
If we go back to the description:
Welcome to our E-commerce website, I wish you enjoy the journey.
- First Man StandingSo if you think about it, it’s not really random https://en.wikipedia.org/wiki/Mersenne_Twister
Since we have 800 outputs, we can recover the state using MT19937
MT19937 facts:
- Once the state is known, you can predict future outputs
- You can also rewind to previous outputs
Confirming MT19937
1) Submit the first 624 values to an MT19937 state recovery tool
2) Predict the next few outputs and compare to the dump.
3) If predictions match, the stream is confirmed as MT19937.This check succeeds:
predicted outputs match the dumped list, so the stream is confirmed
So
We dumped 800 sequential outputs, but the valid invitation is earlier than this window. That means we must rewind the PRNG.
Rewind math
After submitting 624 outputs, the recovery tool’s internal cursor sits at output index 624 of the observed stream. To generate the previous 800 values, we offset by:
-(624 + 800)sage: rc = RandCrack()
....: for v in outputs[:624]:
....: rc.submit(v)
....: rc.offset(-(624 + 800))
....: prev_outputs = [rc.predict_getrandbits(32) for _ in range(800)]
sage: print(prev_outputs)
[2367117681, 42282097, 3934616742, 821412120, 1012857204, 1418681078, etc...This yields the 800 earlier outputs in the stream.
Soo was a dead end for me at first, because based on the hint
First Man Standingi thought the whole idea was submit the first code was generated
┌──(oxfun㉿0xfun)-[~/Desktop/new_ctf/flagyard/NOSJ]
└─$ python3 solve_nosj.py
[*] got 800 codes. first: 4214217566
[*] rewound 800 codes. first: 2426950288So it wasn’t exactly what I expected. The real idea was: submit all the recovered codes, and one of them will be the right invitation
┌──(oxfun㉿0xfun)-[~/Desktop/new_ctf/flagyard/NOSJ]
└─$ python3 solve_nosj.py
[*] got 800 codes. first: 4214217566
[*] rewound 800 codes. first: 2426950288
[?] interesting response at 786: Your flag is: FlagY{x}
here is the right code 2908459947And yeah that’s it ; )









