-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
writeups: arcane runes, microbuns, superguesser
- Loading branch information
Showing
9 changed files
with
151 additions
and
1 deletion.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# Superguesser | ||
|
||
## Solution | ||
|
||
### Part 1 | ||
|
||
```go | ||
seed := time.Now().Unix() | ||
random := rand.New(rand.NewSource(seed)) | ||
randomNumber, maxTries = random.Int63(), 10 | ||
``` | ||
|
||
If we know the seed, we know the random number generated. The Go random number generator will produce the same sequence of numbers for the same seed every time. | ||
|
||
The seed in this case is predictable since it's the current time in Unix seconds. | ||
|
||
We can take note of the Unix second at the time we connected to the challenge and use that to seed our own Go program locally and print out the `randomNumber` generated. | ||
|
||
We also have 10 tries so there's some flexibility to also check subsequent seconds in case of network delays. | ||
|
||
### Part 2 | ||
|
||
```go | ||
seed := time.Now().UnixMilli() | ||
random := rand.New(rand.NewSource(seed)) | ||
randomNumber, maxTries = random.Int63(), 50 | ||
``` | ||
|
||
There a thousand milliseconds in a second. Same as Part 1, we can keep note of the current Unix millisecond we connect to the challenge. Due to network delays we'll need the 50 attempts to try subsequent milliseconds. We'll probably also need to run the challenge a few times until we get a bit lucky. | ||
|
||
Another approach is to simultaneously connect to the challenge server from 2 clients in the hopes of both clients connecting at the same millisecond. If we achieve that, then we have 50+50 attempts at the same number, so we can "guess" it using [Binary Search](https://en.wikipedia.org/wiki/Binary_search_algorithm) (we only need 63 attempts for a 63-bit number.) | ||
|
||
### Part 3 | ||
|
||
```go | ||
seed := time.Now().UnixNano() | ||
random := rand.New(rand.NewSource(seed)) | ||
randomNumber, maxTries = random.Int63(), 100 | ||
``` | ||
|
||
There are a billion nanoseconds in a second. We could still try our luck by spamming attempts but 100 tries are more than enough to perform a [Binary Search](https://en.wikipedia.org/wiki/Binary_search_algorithm) like a pro. |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# Superguesser | ||
|
||
## Solution | ||
|
||
### Part 1 | ||
|
||
```go | ||
seed := time.Now().Unix() | ||
random := rand.New(rand.NewSource(seed)) | ||
randomNumber, maxTries = random.Int63(), 10 | ||
``` | ||
|
||
If we know the seed, we know the random number generated. The Go random number generator will produce the same sequence of numbers for the same seed every time. | ||
|
||
The seed in this case is predictable since it's the current time in Unix seconds. | ||
|
||
We can take note of the Unix second at the time we connected to the challenge and use that to seed our own Go program locally and print out the `randomNumber` generated. | ||
|
||
We also have 10 tries so there's some flexibility to also check subsequent seconds in case of network delays. | ||
|
||
### Part 2 | ||
|
||
```go | ||
seed := time.Now().UnixMilli() | ||
random := rand.New(rand.NewSource(seed)) | ||
randomNumber, maxTries = random.Int63(), 50 | ||
``` | ||
|
||
There a thousand milliseconds in a second. Same as Part 1, we can keep note of the current Unix millisecond we connect to the challenge. Due to network delays we'll need the 50 attempts to try subsequent milliseconds. We'll probably also need to run the challenge a few times until we get a bit lucky. | ||
|
||
Another approach is to simultaneously connect to the challenge server from 2 clients in the hopes of both clients connecting at the same millisecond. If we achieve that, then we have 50+50 attempts at the same number, so we can "guess" it using [Binary Search](https://en.wikipedia.org/wiki/Binary_search_algorithm) (we only need 63 attempts for a 63-bit number.) | ||
|
||
### Part 3 | ||
|
||
```go | ||
seed := time.Now().UnixNano() | ||
random := rand.New(rand.NewSource(seed)) | ||
randomNumber, maxTries = random.Int63(), 100 | ||
``` | ||
|
||
There are a billion nanoseconds in a second. We could still try our luck by spamming attempts but 100 tries are more than enough to perform a [Binary Search](https://en.wikipedia.org/wiki/Binary_search_algorithm) like a pro. |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# Superguesser | ||
|
||
## Solution | ||
|
||
### Part 1 | ||
|
||
```go | ||
seed := time.Now().Unix() | ||
random := rand.New(rand.NewSource(seed)) | ||
randomNumber, maxTries = random.Int63(), 10 | ||
``` | ||
|
||
If we know the seed, we know the random number generated. The Go random number generator will produce the same sequence of numbers for the same seed every time. | ||
|
||
The seed in this case is predictable since it's the current time in Unix seconds. | ||
|
||
We can take note of the Unix second at the time we connected to the challenge and use that to seed our own Go program locally and print out the `randomNumber` generated. | ||
|
||
We also have 10 tries so there's some flexibility to also check subsequent seconds in case of network delays. | ||
|
||
### Part 2 | ||
|
||
```go | ||
seed := time.Now().UnixMilli() | ||
random := rand.New(rand.NewSource(seed)) | ||
randomNumber, maxTries = random.Int63(), 50 | ||
``` | ||
|
||
There a thousand milliseconds in a second. Same as Part 1, we can keep note of the current Unix millisecond we connect to the challenge. Due to network delays we'll need the 50 attempts to try subsequent milliseconds. We'll probably also need to run the challenge a few times until we get a bit lucky. | ||
|
||
Another approach is to simultaneously connect to the challenge server from 2 clients in the hopes of both clients connecting at the same millisecond. If we achieve that, then we have 50+50 attempts at the same number, so we can "guess" it using [Binary Search](https://en.wikipedia.org/wiki/Binary_search_algorithm) (we only need 63 attempts for a 63-bit number.) | ||
|
||
### Part 3 | ||
|
||
```go | ||
seed := time.Now().UnixNano() | ||
random := rand.New(rand.NewSource(seed)) | ||
randomNumber, maxTries = random.Int63(), 100 | ||
``` | ||
|
||
There are a billion nanoseconds in a second. We could still try our luck by spamming attempts but 100 tries are more than enough to perform a [Binary Search](https://en.wikipedia.org/wiki/Binary_search_algorithm) like a pro. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Microbuns | ||
|
||
## Solution | ||
|
||
This challenge is based on the Javascript quirk where `parseInt` will successfully parse a number in a string even though there are non-numeric characters following that number. For example, `parseInt('6pack')` will return `6`. | ||
|
||
Inspired by the bug mentioned [here](https://www.youtube.com/watch?v=iFtcathflSw&t=5886s) -- use this as a "writeup" :) | ||
|
||
Sample payload for the `:user_id` path paremeter: **2**%2F%2E%2E%2F**1** (2/../1) where 2 is your User ID and 1 is the Admin's User ID. | ||
|
||
That payload will bypass this middleware check: | ||
|
||
```javascript | ||
if (req?.params?.user_id) { | ||
if (parseInt(req.params.user_id) !== decoded.user.id) { | ||
return res.status(403).redirect("/login"); | ||
} | ||
} | ||
``` | ||
This should return the private haikus of the Admin user, including the flag in one of them: `curl "$CHALLENGE_URL/user/2%2F%2E%2E%2F1/haikus/private"` |