Rating:
Interacting with the service gives us the following interface:
```console
nc 34.76.165.98 4545
__ __ .__
/ \ / \ ____ | | ____ ____ _____ ____
\ \/\/ // __ \| | _/ ___\/ _ \ / \_/ __ \
\ /\ ___/| |_\ \__( <_> ) Y Y \ ___/
\__/\ / \___ >____/\___ >____/|__|_| /\___ >
\/ \/ \/ \/ \/
(>'-')>
Hello! this is Kirby!!! I love to check the spelling of the FLAG!
You have to spell it correctly and you'll win! Good luck!!!
Press ENTER to start...
[?]> 123
Oops!!! Game Over!!!
```
After playing around with the service a for a bit, we can discover that the flag is 33 characters
long.
```console
nc 34.76.165.98 4545
__ __ .__
/ \ / \ ____ | | ____ ____ _____ ____
\ \/\/ // __ \| | _/ ___\/ _ \ / \_/ __ \
\ /\ ___/| |_\ \__( <_> ) Y Y \ ___/
\__/\ / \___ >____/\___ >____/|__|_| /\___ >
\/ \/ \/ \/ \/
(>'-')>
Hello! this is Kirby!!! I love to check the spelling of the FLAG!
You have to spell it correctly and you'll win! Good luck!!!
Press ENTER to start...
[?]> AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
<(^-^)>
Thanks for playing!
Hmmmm!!! Don't be sad!!! Your score = 0/33
```
Since the challenge gives us an oracle that tells us how many characters matches the flag, we can
just iterate it character by character using the following script:
```python
#!/usr/bin/env python
from pwn import *
import string
# 24 b"\n<(^-^)>\nThanks for playing!\nHmmmm!!! Don't be sad!!! Your score = 9/33\n"
flag_len = 24 + len("VULNCON{}")
# Exclude whitespace
CHARSET = string.printable[:94]
def attempt(data):
p = remote("34.76.165.98", 4545)
data = "VULNCON{" + data + "A" * (24 - len(data)) + "}"
p.sendline(b"")
p.sendline(data.encode())
p.recvuntil(b"[?]> ")
data = p.recvall()
score = None
if b"Your score" in data:
temp = data.strip()
score = int(temp[temp.index(b'=') + 2:temp.index(b'/')])
p.close()
return data, score
def main():
# The flag only has 9 correct characters at this point.
# e.g. starting = "VULNCON{" + "A" * 24 + "}"
middle_part = ""
matching = 9
for i in range(24):
for candidate in CHARSET:
result, score = attempt(middle_part + candidate)
print(result, score, middle_part)
if score > matching:
middle_part += candidate
matching = score
break
log.success("Flag: " + "VULNCON{" + middle_part + "}")
if __name__ == '__main__':
main()
```
Running the exploit gives us the flag eventually:
```console
$ python exploit.py
[+] Opening connection to 34.76.165.98 on port 4545: Done
[+] Receiving all data: Done (72B)
[*] Closed connection to 34.76.165.98 port 4545
b"\n<(^-^)>\nThanks for playing!\nHmmmm!!! Don't be sad!!! Your score = 9/33\n" 9
[+] Opening connection to 34.76.165.98 on port 4545: Done
[+] Receiving all data: Done (72B)
[*] Closed connection to 34.76.165.98 port 4545
b"\n<(^-^)>\nThanks for playing!\nHmmmm!!! Don't be sad!!! Your score = 9/33\n" 9
[+] Opening connection to 34.76.165.98 on port 4545: Done
[+] Receiving all data: Done (72B)
[*] Closed connection to 34.76.165.98 port 4545
b"\n<(^-^)>\nThanks for playing!\nHmmmm!!! Don't be sad!!! Your score = 9/33\n" 9
[+] Opening connection to 34.76.165.98 on port 4545: Done
[+] Receiving all data: Done (72B)
[*] Closed connection to 34.76.165.98 port 4545
b"\n<(^-^)>\nThanks for playing!\nHmmmm!!! Don't be sad!!! Your score = 9/33\n" 9
[+] Opening connection to 34.76.165.98 on port 4545: Done
...
[*] Closed connection to 34.76.165.98 port 4545
b"\n<(^-^)>\nThanks for playing!\nHmmmm!!! Don't be sad!!! Your score = 32/33\n" 32 k1rby_7h3_5p3ll_ch3ck3r
[+] Opening connection to 34.76.165.98 on port 4545: Done
[+] Receiving all data: Done (73B)
[*] Closed connection to 34.76.165.98 port 4545
b"\n<(^-^)>\nThanks for playing!\nHmmmm!!! Don't be sad!!! Your score = 32/33\n" 32 k1rby_7h3_5p3ll_ch3ck3r
[+] Opening connection to 34.76.165.98 on port 4545: Done
[+] Receiving all data: Done (58B)
[*] Closed connection to 34.76.165.98 port 4545
b'\n<(^-^)>\nThanks for playing!\nYeyyyy!!! Your score = 33/33\n' 33 k1rby_7h3_5p3ll_ch3ck3r
[+] Flag: VULNCON{k1rby_7h3_5p3ll_ch3ck3r!}
```
**Flag:** `VULNCON{k1rby_7h3_5p3ll_ch3ck3r!}`