Skip to content

Commit 185ad9f

Browse files
committed
Add 2022 leet challenges
1 parent e78c311 commit 185ad9f

14 files changed

+571
-22
lines changed

Diff for: _posts/2022-11-08-diffie-hellman-guide.md

+140
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
---
2+
layout: post
3+
title: "1337 Crypto Guide - Diffie Hellman"
4+
author: vEvergarden
5+
hide: "true"
6+
---
7+
8+
Let's begin by introducing our two favourite people - Alice and Bob.
9+
10+
![](https://i.imgur.com/46b0dOe.png)
11+
12+
13+
Alice and Bob have a mutual enemy - Eve.
14+
![](https://i.imgur.com/HPTmmsh.png)
15+
16+
17+
Eve is notorious for *eaves*dropping on other people's conversations and listening to all of their gossip. One day, Alice and Bob decide that they've had enough of Eve's eavesdropping. They want to communicate in public, but in a way such that only they themselves can understand each other.
18+
19+
One way they can accomplish this is by speaking a different language that Eve doesn't understand. Now, they can freely talk to each other in the open without worrying about Eve listening in on their conversations.
20+
21+
Similarly, **cryptographic ciphers** are another way Alice and Bob can securely communicate with each other. If they decide on a secret key on a slip of paper beforehand (similar to a password), they can **encrypt** all of their messages with that secret key. To Eve who doesn't know the secret key, all of Alice's and Bob's messages are just random garbage that she can't understand.
22+
23+
![](https://i.imgur.com/t5DAg1l.png)
24+
25+
26+
Now, all is well - Alice and Bob have found a way to talk without Eve understanding what they're saying.
27+
28+
29+
### Details
30+
[AES](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) is the most widely used block cipher - it's used to encrypt/decrypt messages with a given secret key. The length of the key and message must be multiples of 16 bytes; for the message, we can simply add a few extra bytes at the end; for the key, we can apply the [SHA-256](https://www.n-able.com/blog/sha-256-encryption) hash function to produce a 32-byte hash.
31+
32+
The Python `pycryptodome` library offers a wide range of cryptography tools - try playing around with the code below!
33+
```python
34+
from Crypto.Util.Padding import pad
35+
from Crypto.Cipher import AES
36+
from hashlib import sha256
37+
38+
# we use SHA256 to ensure that the key is the right length
39+
key = sha256(b'my secret key').digest()
40+
cipher = AES.new(key, AES.MODE_ECB)
41+
42+
# the length of your message has to be a multiple of 16, so we pad it with some extra bytes
43+
message = pad(b'This is a secret message!', 16)
44+
ciphertext = cipher.encrypt(message)
45+
print("Encrypted message:", ciphertext)
46+
47+
# Decryption is very similar!
48+
plaintext = cipher.decrypt(ciphertext)
49+
print("Decrypted message:", plaintext)
50+
```
51+
52+
## Part 2
53+
54+
Five years later, Alice and Bob have moved to different parts of the world. They can't talk to each other in-person anymore, but they would like to communicate digitally. Unfortunately, Bob has forgotten the original secret key that they decided on, and (even after 5 years) they're still worried about Eve spying on their conversations.
55+
56+
What's different is that this time there's **no easy way to decide on a secret key**. For example:
57+
- If they mail a slip of paper with the key written on it, someone could intercept it midway
58+
- If they send it through e-mail, someone hosting the mail server may see the secret key
59+
- If they say what the key is over a call, someone could tap in on their conversation
60+
61+
![](https://i.imgur.com/pffi11V.png)
62+
63+
Think about this problem for a bit and see if you can come up with your own ideas. Is it possible to decide on something secret over a network where anyone can see what you send?
64+
65+
Yes! In fact, the **Diffie-Hellman Key Exchange** is one method for securely exchanging a secret key. Alice and Bob will each generate a "public" and "private" key - using those, they can then generate a shared secret that only they know. Even if Eve sees all of the communication between Alice and Bob, she can't figure out what their shared secret is.
66+
67+
### Details
68+
69+
The Diffie-Hellman Key Exchange revolves around some mathematical concepts - but don't be intimidated!
70+
71+
The process begins with:
72+
- Alice randomly picks an integer $a$
73+
- Bob randomly picks an integer $b$
74+
75+
$a$ and $b$ are Alice's and Bob's personal "private keys". If anyone is able to guess or brute-force either of these private keys, they can recover the shared secret. Usually, $a$ and $b$ are on the order of $2^{1024}$, making it computationally infeasible to try out all possibilities.
76+
77+
Beforehand, Alice and Bob have publicly decided on the integers $g$ and $p$ - Eve will know these values.
78+
79+
Now:
80+
- Alice calculates $g^a \mod p$ and sends it publicly to Bob
81+
- Bob calculates $g^b \mod p$ and sends it publicly to Alice
82+
- (Here, $g^x \mod p$ is the remainder when $g^x$ is divided by p)
83+
84+
![](https://i.imgur.com/jGHumNZ.png)
85+
86+
87+
88+
**The key idea is that: even if Eve knows $g$, $p$, and $g^a \mod p$, she won't be able to find the value of $a$**. Not even Bob will know the value of $a$ - only Alice knows $a$ because she was the one who chose it.
89+
90+
Similarly, neither Alice nor Eve know the value of $b$, even though they know $g$, $p$, and $g^b \mod p$
91+
92+
The problem of finding either $a$ or $b$ in these cases is known as the [**Discrete Logarithm Problem**](https://en.wikipedia.org/wiki/Discrete_logarithm). There are faster solutions than simply trying out all values of $a$, but they are still far too slow to find $a$ or $b$ in reasonable time.
93+
94+
Alice, now knowing the value of $g^b$, can compute $(g^b) ^a \equiv g^{ba} \mod p$
95+
96+
Bob, now knowing the value of $g^a$, can compute $(g^a) ^ b \equiv g ^ {ab} \mod p$.
97+
98+
![](https://i.imgur.com/OnAbfVE.png)
99+
100+
101+
Since $g^{ab} \equiv g^{ba} \mod p$, **Alice and Bob have successfully decided on a secret value: $g^{ab} \mod p$!** Even though Eve knows the values:
102+
- $g$
103+
- $p$
104+
- $g^a \mod p$
105+
- $g^b \mod p$
106+
107+
there is no way for her to find $g^{ab} \mod p$ because the **Discrete Logarithm Problem** is computationally hard and will take a *very, very* long time to solve.
108+
109+
```python
110+
from Crypto.Util.number import getPrime
111+
from random import randint
112+
113+
p = getPrime(1024) # generate a large modulus
114+
g = 2
115+
116+
alice_secret = randint(0, p)
117+
alice_public = pow(g, alice_secret, p) # g^a mod p
118+
119+
bob_secret = randint(0, p)
120+
bob_public = pow(g, bob_secret, p) # g^b mod p
121+
122+
# Alice calculates the shared secret: (g^b)^a == g^(ba) mod p
123+
shared_secret_A = pow(bob_public, alice_secret, p)
124+
125+
# Bob calculates the shared secret: (g^a)^b == g^(ab) mod p
126+
shared_secret_B = pow(alice_public, bob_secret, p)
127+
128+
# They've successfully shared a secret that only they know!
129+
assert shared_secret_A == shared_secret_B
130+
```
131+
132+
Now, Alice and Bob can continue along their merry ways and use AES, with the shared secret as the AES key, to securely encrypt their messages (see Part 1 for details).
133+
134+
# Summary
135+
136+
We started off with Alice and Bob - they wanted to communicate securely because Eve was eavesdropping on their conversations. We accomplished this by making Alice and Bob decide on a secret, then using a cryptographic cipher like [AES](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) to encrypt/decrypt their messages.
137+
138+
Then, we pondered how we could decide a shared secret if Eve could also eavesdrop on that process. Ultimately, the **Diffie-Hellman Key Exchange** came to the rescue - it relies on the Discrete Logarithm Problem being hard to solve. Even if Eve can see everything that Alice sends to Bob and everything that Bob sends to Alice, she still won't be able to calculate Alice and Bob's shared secret. From there, Alice and Bob can use a cipher like AES, as in the first part.
139+
140+
![](https://i.imgur.com/ZY1jz82.png)

Diff for: _posts/2022-11-08-jail-challenges-guide.md

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
layout: post
3+
title: "1337 Misc Guide - Jail Challenges in CTFs"
4+
author: rctcwyvrn
5+
---
6+
7+
### Jail challenges in CTFs
8+
9+
Jail challenges are a kind of `misc` category challenge in CTFs where the server lets you run arbitrary code, but subject to certain restrictions. For example python jails might not let you import anything or limit you to a very limited character set.
10+
11+
Typically in jail challenges the goal is to spawn a shell, ie to convince the jail to let you execute something like `bash` or `sh`.
12+
13+
For example a python jail might call `exec` on your input, but doing `exec("import os; os.system('bash')")` would let you escape into the shell.
14+
- https://docs.python.org/3/library/functions.html#exec
15+
- https://docs.python.org/3/library/os.html#os.system
16+
17+
Now these examples are for python jails, in this challenge you'll be in a racket jail. Convincing the jail to allow you execute the racket equivalent like `os.system("bash")` will usually require some manipulation of your input in order to work around the blocklist or restrictions put in place by the jail, and it'll be a similar story in this challenge.
18+
19+

Diff for: _posts/2022-11-08-reversing-guide.md

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
---
2+
layout: post
3+
title: "1337 Reversing Guide - "
4+
author: Kevin
5+
hide: "true"
6+
---
7+
8+
9+
## What is reverse engineering?
10+
In the context of software engineering, reverse engineering is the process of taking a program and finding out what it does. This is a difficult process because source code is not usually provided which means that the only thing you can work with is the machine code that the program is comprised of. Luckily, there are tools out there that can make your life a lot easier.
11+
12+
## How do I reverse engineer a program?
13+
A program is comprised of machine code that in not legible by a human. This is why when you open an `.exe` file in a text editor it just looks like garbage. So the first step in reverse engineering is to turn this machine code into something a person can read. Usually, a disassembler is used to convert machine code into human readable assembly.
14+
15+
![disassembly.PNG](/assets/images/rev-guide/disassembly.PNG)
16+
<center> <em>The result of disassembling a program using a disassembler.</em> </center></br>
17+
18+
However, it is still difficult to understand what is going on. Fortunately, we can do better than the disassembly. There are programs called decompilers that will try to decompile the program into C like source code.
19+
20+
![decompile.PNG](/assets/images/rev-guide/decompile.PNG)
21+
<center> <em>The result of decompiling a program using a decompiler.</em> </center></br>
22+
23+
## Disassemblers vs. Decompilers
24+
25+
One may be asking why would they ever use a disassembler over a decompiler. The answer is that while decompilers generate output that is easier to understand the way it does this is through a heuristic. This means that sometimes that decompilers will output something that does not make any sense at all. On the other hand, disassemblers generate their output by directly translating machine code to assembly using documentation from the instruction set that the CPU must follow. This is why its still important to be able to understand assembly.
26+
27+
## Static Analysis vs. Dynamic Analysis
28+
There are two approaches to reverse engineering; static analysis and dynamic analysis.</br>
29+
Static analysis is the practice of reverse engineering the program without ever running it. This involves figuring out what the machine code is trying to do using some of the tools that we have mentioned before.
30+
31+
Dynamic analysis is all about running the program to figure out what its doing. It involves attaching a debugger to the program when it is running and then examining the state of the during the execution of the program. The state of the program includes things such as register values and what is in memory at the time of execution.
32+
33+
There is no single best approach and one may be better than the other depending on the program that you are trying to analyze.
34+
35+
## Tools
36+
Okay, now for the important part. What are these tools that I have been talking about all this time?
37+
38+
For static analysis, `Ghidra` is an open source disassembler/decompiler that is developed by the NSA. It is both a disassembler and decompiler. The best part is its open source and free!
39+
40+
For dynamic analysis, personally I use `gdb` plus an extension like `gef` that provides a couple more features.
41+

Diff for: assets/1337-2022/crypto/main.py

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
from Crypto.Util.Padding import pad
2+
from Crypto.Util.number import getPrime
3+
from Crypto.Cipher import AES
4+
from hashlib import sha256
5+
from random import randint
6+
from secrets import flag # imports the challenge flag
7+
import sys
8+
9+
sys.setrecursionlimit(10**8)
10+
11+
p = getPrime(1024)
12+
G = [[1, 1337], [0, 1]]
13+
14+
# multiply two 2x2 matrices A and B:
15+
def mult(A, B):
16+
result = [[0, 0], [0, 0]]
17+
for i in range(2):
18+
for j in range(2):
19+
result[i][j] = (A[i][0] * B[0][j] + A[i][1] * B[1][j]) % p
20+
return result
21+
22+
23+
# compute A^n with exponentiation by squaring
24+
def exp(A, n):
25+
if n == 0:
26+
return [[1, 0], [0, 1]]
27+
half = exp(A, n // 2)
28+
if n % 2 == 0:
29+
return mult(half, half)
30+
return mult(A, mult(half, half))
31+
32+
33+
# generate Alice's private and public keys
34+
alice_secret = randint(0, p)
35+
alice_public = exp(G, alice_secret)
36+
37+
# generate Bob's private and public keys
38+
bob_secret = randint(0, p)
39+
bob_public = exp(G, bob_secret)
40+
41+
# generate their shared secrets & check that they're the same
42+
shared_secret_A = exp(bob_public, alice_secret)
43+
shared_secret_B = exp(alice_public, bob_secret)
44+
assert shared_secret_A == shared_secret_B
45+
46+
# encrypt the flag with the shared secret
47+
key = str(
48+
shared_secret_A[0][0]
49+
+ shared_secret_A[0][1]
50+
+ shared_secret_A[1][0]
51+
+ shared_secret_A[1][1]
52+
).encode()
53+
key = sha256(key).digest()
54+
cipher = AES.new(key, AES.MODE_ECB)
55+
ciphertext = cipher.encrypt(pad(flag, 16))
56+
57+
print("p:", p)
58+
print("Alice's public key:", alice_public)
59+
print("Bob's public key:", bob_public)
60+
print("Ciphertext:", ciphertext.hex())

Diff for: assets/1337-2022/crypto/output.txt

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
p: 146635760303605976983894071500931857745973394259316464700291483611526724218460127444254168689045959985005212817040847174467141482547356061539722956992438198039196888496774232353702637340110963371323293180453107143830592752177650175267498096676840496849442055749071547763221826370121367266367265736640016224849
2+
Alice's public key: [[1, 122593569202713047256910856823064610802102165848412863419714367343535068432181229651183057378109240921706373026419955238421640119452077037295962596003436443748125952314067117706872613751900101093292596858137281488155807864319911989756603206024363635538681795330100292400684134799357570963098198243796012905071], [0, 1]]
3+
Bob's public key: [[1, 142857700274726494408753852766748133062989262570137331655228102720787303055171574691107864588269598429108651878879476731967757999196356469620766415382477392868604610906632622085379260676352636736367989787236537655987365802465995407192642985159206280944380481606853288780557358104659172496832399866770779719373], [0, 1]]
4+
Ciphertext: 214ede254e789f9cd153b54ca115d5c2dce406dc9552bfd00241ed2054706f91

Diff for: assets/1337-2022/misc/jail1.rkt

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#lang racket
2+
3+
(define (jail)
4+
; Prepare the jail namespace
5+
(parameterize ([current-namespace (make-base-namespace)])
6+
; Inside your jail you have racket/system and racket/base
7+
; https://docs.racket-lang.org/reference/subprocess.html#%28mod-path._racket%2Fsystem%29
8+
(namespace-require 'racket/system)
9+
(printf "> ")
10+
(let ([stx (syntax->datum (read-syntax))])
11+
(printf "Your input: ~a\n" stx)
12+
(printf "Result: ~a \n" (eval stx)))))
13+
14+
(module+ main
15+
(displayln "Welcome to Racket jail, where people who complain about the usage of Racket in 110 are sentenced to, forced to live in a Racket REPL for all eternity")
16+
(displayln "'Racket has no practical uses' you say? Well you better learn about some practical uses if you wanna escape!\n")
17+
(displayln "Hint: Successfully run the `get-flag` command in a shell to obtain the flag. You'll need to escape from Racket into the system shell in order to do it")
18+
(jail)
19+
(displayln "Exiting"))

Diff for: assets/1337-2022/misc/jail2.rkt

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#lang racket
2+
3+
; Just a conversion function
4+
(define (datum->string d)
5+
(cond
6+
[(string? d) d]
7+
[(number? d) (number->string d)]
8+
[(symbol? d) (symbol->string d)]
9+
[else (error "datum->string: not a terminal")]))
10+
11+
; None of these functions are allowed this time! No easy escape tools!
12+
(define (strictly-forbidden? x)
13+
(ormap (curry string-contains? x)
14+
(list "system" "process" "read-eval-print-loop" "shell-execute")))
15+
16+
; Have you used your one exception?
17+
(define has-seen-allowed-exception #f)
18+
19+
; A string is allowed if it it is one of:
20+
; - A single character in length
21+
; - A string containing "string" (https://docs.racket-lang.org/reference/strings.html)
22+
; - A string containing "quote" (https://docs.racket-lang.org/guide/quote.html https://docs.racket-lang.org/guide/qq.html)
23+
(define (allowed? term)
24+
(or (string-contains? term "string")
25+
(string-contains? term "quote")
26+
(eq? (string-length term) 1)))
27+
28+
; Check that each term follows the requirements
29+
(define (check term)
30+
(printf "check: ~a (has-seen-allowed-exception ~a) \n" term has-seen-allowed-exception)
31+
(cond
32+
; Never allow any strictly forbidden terms
33+
[(strictly-forbidden? term) #f]
34+
; Check if the term is allowed
35+
[(allowed? term) #t]
36+
; You're allowed to have ONE term that is not normally allowed! Use it wisely
37+
[has-seen-allowed-exception #f]
38+
[else
39+
(begin
40+
(set! has-seen-allowed-exception #t)
41+
#t)]))
42+
43+
; Walk down the syntax tree to check that everything follows the requirements
44+
(define (valid stx)
45+
(match stx
46+
[`(,xs ...) (andmap valid xs)]
47+
[x (check (datum->string x))]))
48+
49+
(define (jail)
50+
; Prepare the jail namespace
51+
(parameterize ([current-namespace (make-base-namespace)])
52+
; Inside your jail you have racket/system and racket/base
53+
; https://docs.racket-lang.org/reference/subprocess.html#%28mod-path._racket%2Fsystem%29
54+
(namespace-require 'racket/system)
55+
(printf "> ")
56+
(let ([stx (syntax->datum (read-syntax))])
57+
(printf "Your input: ~a\n" stx)
58+
; Check the given racket expression
59+
(if (valid stx)
60+
; if it's valid, eval it https://docs.racket-lang.org/guide/eval.html
61+
(printf "Result: ~a \n" (eval stx))
62+
(printf "Invalid input: ~a \n" stx)))))
63+
64+
(module+ main
65+
(displayln "Well done escaping out of that last jail, but there's no way you'll get out of this one!")
66+
(displayln "We've taken away all of your escape tools so there should be no way of escaping")
67+
(displayln "PS: Warden Gregor felt bad for you so he said to give you one exception to our rules, it's not like you can escape with just one exception anyway")
68+
(displayln "Hint: Successfully run the `get-flag` command to obtain the flag")
69+
(jail)
70+
(displayln "Exiting"))

Diff for: assets/1337-2022/pwn/playground

17.4 KB
Binary file not shown.

Diff for: assets/1337-2022/rev/rando

11.1 KB
Binary file not shown.

0 commit comments

Comments
 (0)