/usr/local/bin/backup
There was an unusually binary with SUID bit set at /usr/local/bin/backup
In fact, I remember this binary from the Node.js script; app.js
, from the downloaded backup archive
This binary was called from a function to conduct the archiving operation
mark@node:/var$ /usr/local/bin/backup
-bash: /usr/local/bin/backup: Permission denied
I executed the binary to see how it would behave I got denied for permission
mark@node:/var$ ll /usr/local/bin/backup
-rwsr-xr-- 1 root admin 16484 Sep 3 2017 /usr/local/bin/backup*
Indeed
Only the root
user and members of theadmin
group can execute this binary.
mark@node:/var$ id
uid=1001(mark) gid=1001(mark) groups=1001(mark)
The mark
user is none of them
mark@node:/var/scheduler$ groups tom
tom : tom adm cdrom sudo dip plugdev lpadmin sambashare admin
The tom
user is part of the admin
group
Although the current user (mark
) does not have permission to execute, I can still check out what this binary does
Reading binary (Getting Trolled)
mark@node:/var$ file /usr/local/bin/backup
/usr/local/bin/backup: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=343cf2d93fb2905848a42007439494a2b4984369, not stripped
It is a 32-bit executable.
mark@node:/var$ strings /usr/local/bin/backup
/lib/ld-linux.so.2
libc.so.6
_IO_stdin_used
setuid
strcpy
exit
sprintf
srand
fopen
strncpy
puts
time
clock
getpid
fgets
strstr
strcspn
fclose
strcat
remove
system
geteuid
strchr
access
strcmp
__libc_start_main
__gmon_start__
GLIBC_2.1
GLIBC_2.0
PTRh
WVSQ
Y[^_]
UWVS
t$,U
[^_]
[37m
[33m
%s[!]%s %s
[32m
%s[+]%s %s
%s[+]%s Starting archiving %s
____________________________________________________
/ \
| _____________________________________________ |
| | | |
| | Secure Backup v1.0 | |
| |_____________________________________________| |
| |
\_____________________________________________________/
\_______________________________________/
_______________________________________________
_-' .-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. --- `-_
_-'.-.-. .---.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.--. .-.-.`-_
_-'.-.-.-. .---.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-`__`. .-.-.-.`-_
_-'.-.-.-.-. .-----.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-----. .-.-.-.-.`-_
_-'.-.-.-.-.-. .---.-. .-----------------------------. .-.---. .---.-.-.-.`-_
:-----------------------------------------------------------------------------:
`---._.-----------------------------------------------------------------._.---'
Could not open file
Validated access token
Ah-ah-ah! You didn't say the magic word!
Finished! Encoded backup is below:
UEsDBDMDAQBjAG++IksAAAAA7QMAABgKAAAIAAsAcm9vdC50eHQBmQcAAgBBRQEIAEbBKBl0rFrayqfbwJ2YyHunnYq1Za6G7XLo8C3RH/hu0fArpSvYauq4AUycRmLuWvPyJk3sF+HmNMciNHfFNLD3LdkGmgwSW8j50xlO6SWiH5qU1Edz340bxpSlvaKvE4hnK/oan4wWPabhw/2rwaaJSXucU+pLgZorY67Q/Y6cfA2hLWJabgeobKjMy0njgC9c8cQDaVrfE/ZiS1S+rPgz/e2Pc3lgkQ+lAVBqjo4zmpQltgIXauCdhvlA1Pe/BXhPQBJab7NVF6Xm3207EfD3utbrcuUuQyF+rQhDCKsAEhqQ+Yyp1Tq2o6BvWJlhtWdts7rCubeoZPDBD6Mejp3XYkbSYYbzmgr1poNqnzT5XPiXnPwVqH1fG8OSO56xAvxx2mU2EP+Yhgo4OAghyW1sgV8FxenV8p5c+u9bTBTz/7WlQDI0HUsFAOHnWBTYR4HTvyi8OPZXKmwsPAG1hrlcrNDqPrpsmxxmVR8xSRbBDLSrH14pXYKPY/a4AZKO/GtVMULlrpbpIFqZ98zwmROFstmPl/cITNYWBlLtJ5AmsyCxBybfLxHdJKHMsK6Rp4MO+wXrd/EZNxM8lnW6XNOVgnFHMBsxJkqsYIWlO0MMyU9L1CL2RRwm2QvbdD8PLWA/jp1fuYUdWxvQWt7NjmXo7crC1dA0BDPg5pVNxTrOc6lADp7xvGK/kP4F0eR+53a4dSL0b6xFnbL7WwRpcF+Ate/Ut22WlFrg9A8gqBC8Ub1SnBU2b93ElbG9SFzno5TFmzXk3onbLaaEVZl9AKPA3sGEXZvVP+jueADQsokjJQwnzg1BRGFmqWbR6hxPagTVXBbQ+hytQdd26PCuhmRUyNjEIBFx/XqkSOfAhLI9+Oe4FH3hYqb1W6xfZcLhpBs4Vwh7t2WGrEnUm2/F+X/OD+s9xeYniyUrBTEaOWKEv2NOUZudU6X2VOTX6QbHJryLdSU9XLHB+nEGeq+sdtifdUGeFLct+Ee2pgR/AsSexKmzW09cx865KuxKnR3yoC6roUBb30Ijm5vQuzg/RM71P5ldpCK70RemYniiNeluBfHwQLOxkDn/8MN0CEBr1eFzkCNdblNBVA7b9m7GjoEhQXOpOpSGrXwbiHHm5C7Zn4kZtEy729ZOo71OVuT9i+4vCiWQLHrdxYkqiC7lmfCjMh9e05WEy1EBmPaFkYgxK2c6xWErsEv38++8xdqAcdEGXJBR2RT1TlxG/YlB4B7SwUem4xG6zJYi452F1klhkxloV6paNLWrcLwokdPJeCIrUbn+C9TesqoaaXASnictzNXUKzT905OFOcJwt7FbxyXk0z3FxD/tgtUHcFBLAQI/AzMDAQBjAG++IksAAAAA7QMAABgKAAAIAAsAAAAAAAAAIIC0gQAAAAByb290LnR4dAGZBwACAEFFAQgAUEsFBgAAAAABAAEAQQAAAB4EAAAAAA==
/root
/etc
/tmp/.backup_%i
/usr/bin/zip -r -P magicword %s %s > /dev/null
/usr/bin/base64 -w0 %s
The target path doesn't exist
;*2$"
GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
[...REDACTED...]
I can extract ASCII strings from the binary with strings command
It also appears to archive some directories with zip command with the
-P
to set the password; magicword
it is then converted to a base64 string and
gets printed out
This all is just an assumption. I would have to open this up in a disassembler in order to precisely find out what it does.
But for now, I will continue
mark@node:/dev/shm$ echo 'UEsDBDMDAQBjAG++IksAAAAA7QMAABgKAAAIAAsAcm9vdC50eHQBmQcAAgBBRQEIAEbBKBl0rFrayqfbwJ2YyHunnYq1Za6G7XLo8C3RH/hu0fArpSvYauq4AUycRmLuWvPyJk3sF+HmNMciNHfFNLD3LdkGmgwSW8j50xlO6SWiH5qU1Edz340bxpSlvaKvE4hnK/oan4wWPabhw/2rwaaJSXucU+pLgZorY67Q/Y6cfA2hLWJabgeobKjMy0njgC9c8cQDaVrfE/ZiS1S+rPgz/e2Pc3lgkQ+lAVBqjo4zmpQltgIXauCdhvlA1Pe/BXhPQBJab7NVF6Xm3207EfD3utbrcuUuQyF+rQhDCKsAEhqQ+Yyp1Tq2o6BvWJlhtWdts7rCubeoZPDBD6Mejp3XYkbSYYbzmgr1poNqnzT5XPiXnPwVqH1fG8OSO56xAvxx2mU2EP+Yhgo4OAghyW1sgV8FxenV8p5c+u9bTBTz/7WlQDI0HUsFAOHnWBTYR4HTvyi8OPZXKmwsPAG1hrlcrNDqPrpsmxxmVR8xSRbBDLSrH14pXYKPY/a4AZKO/GtVMULlrpbpIFqZ98zwmROFstmPl/cITNYWBlLtJ5AmsyCxBybfLxHdJKHMsK6Rp4MO+wXrd/EZNxM8lnW6XNOVgnFHMBsxJkqsYIWlO0MMyU9L1CL2RRwm2QvbdD8PLWA/jp1fuYUdWxvQWt7NjmXo7crC1dA0BDPg5pVNxTrOc6lADp7xvGK/kP4F0eR+53a4dSL0b6xFnbL7WwRpcF+Ate/Ut22WlFrg9A8gqBC8Ub1SnBU2b93ElbG9SFzno5TFmzXk3onbLaaEVZl9AKPA3sGEXZvVP+jueADQsokjJQwnzg1BRGFmqWbR6hxPagTVXBbQ+hytQdd26PCuhmRUyNjEIBFx/XqkSOfAhLI9+Oe4FH3hYqb1W6xfZcLhpBs4Vwh7t2WGrEnUm2/F+X/OD+s9xeYniyUrBTEaOWKEv2NOUZudU6X2VOTX6QbHJryLdSU9XLHB+nEGeq+sdtifdUGeFLct+Ee2pgR/AsSexKmzW09cx865KuxKnR3yoC6roUBb30Ijm5vQuzg/RM71P5ldpCK70RemYniiNeluBfHwQLOxkDn/8MN0CEBr1eFzkCNdblNBVA7b9m7GjoEhQXOpOpSGrXwbiHHm5C7Zn4kZtEy729ZOo71OVuT9i+4vCiWQLHrdxYkqiC7lmfCjMh9e05WEy1EBmPaFkYgxK2c6xWErsEv38++8xdqAcdEGXJBR2RT1TlxG/YlB4B7SwUem4xG6zJYi452F1klhkxloV6paNLWrcLwokdPJeCIrUbn+C9TesqoaaXASnictzNXUKzT905OFOcJwt7FbxyXk0z3FxD/tgtUHcFBLAQI/AzMDAQBjAG++IksAAAAA7QMAABgKAAAIAAsAAAAAAAAAIIC0gQAAAAByb290LnR4dAGZBwACAEFFAQgAUEsFBgAAAAABAAEAQQAAAB4EAAAAAA==' | base64 -d > decoded.zip
So I just decoded the base64 string of the password-protected archive and saved it as decoded.zip
mark@node:/dev/shm$ file decoded.zip
decoded.zip: Zip archive data
It is indeed a Zip archive
mark@node:/dev/shm$ unzip decoded.zip
Archive: decoded.zip
skipping: root.txt need PK compat. v5.1 (can do v4.6)
Attempting to extract the content, which appears to be the root.txt
file, resulted in failure as it requires the version 5.1
┌──(kali㉿kali)-[~/archive/htb/labs/node]
└─$ 7z x decoded.zip
7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,64 bits,32 CPUs 11th Gen Intel(R) Core(TM) i9-11900H @ 2.50GHz (806D1),ASM,AES-NI)
Scanning the drive for archives:
1 file, 1141 bytes (2 KiB)
Extracting archive: huh.zip
--
Path = decoded.zip
Type = zip
Physical Size = 1141
Enter password (will not be echoed):
Everything is Ok
Size: 2584
Compressed: 1141
I transferred it over to Kali and used 7z for extraction.
It prompted for password and I put magicword
It would appear the file got extracted.
┌──(kali㉿kali)-[~/archive/htb/labs/node]
└─$ cat root.txt
QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
QQQQQQQQQQQQQQQQQQQWQQQQQWWWBBBHHHHHHHHHBWWWQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
QQQQQQQQQQQQQQQD!`__ssaaaaaaaaaass_ass_s____. -~""??9VWQQQQQQQQQQQQQQQQQQQ
QQQQQQQQQQQQQP'_wmQQQWWBWV?GwwwmmWQmwwwwwgmZUVVHAqwaaaac,"?9$QQQQQQQQQQQQQQ
QQQQQQQQQQQW! aQWQQQQW?qw#TTSgwawwggywawwpY?T?TYTYTXmwwgZ$ma/-?4QQQQQQQQQQQ
QQQQQQQQQQW' jQQQQWTqwDYauT9mmwwawww?WWWWQQQQQ@TT?TVTT9HQQQQQQw,-4QQQQQQQQQ
QQQQQQQQQQ[ jQQQQQyWVw2$wWWQQQWWQWWWW7WQQQQQQQQPWWQQQWQQw7WQQQWWc)WWQQQQQQQ
QQQQQQQQQf jQQQQQWWmWmmQWU???????9WWQmWQQQQQQQWjWQQQQQQQWQmQQQQWL 4QQQQQQQQ
QQQQQQQP'.yQQQQQQQQQQQP" <wa,.!4WQQQQQQQWdWP??!"??4WWQQQWQQc ?QWQQQQQ
QQQQQP'_a.<aamQQQW!<yF "!` .. "??$Qa "WQQQWTVP' "??' =QQmWWV?46/ ?QQQQQ
QQQP'sdyWQP?!`.-"?46mQQQQQQT!mQQgaa. <wWQQWQaa _aawmWWQQQQQQQQQWP4a7g -WWQQ
QQ[ j@mQP'adQQP4ga, -????" <jQQQQQWQQQQQQQQQWW;)WQWWWW9QQP?"` -?QzQ7L ]QQQ
QW jQkQ@ jWQQD'-?$QQQQQQQQQQQQQQQQQWWQWQQQWQQQc "4QQQQa .QP4QQQQfWkl jQQQ
QE ]QkQk $D?` waa "?9WWQQQP??T?47`_aamQQQQQQWWQw,-?QWWQQQQQ`"QQQD\Qf(.QWQQ
QQ,-Qm4Q/-QmQ6 "WWQma/ "??QQQQQQL 4W"- -?$QQQQWP`s,awT$QQQ@ "QW@?$:.yQQQQ
QQm/-4wTQgQWQQ, ?4WWk 4waac -???$waQQQQQQQQF??'<mWWWWWQW?^ ` ]6QQ' yQQQQQ
QQQQw,-?QmWQQQQw a, ?QWWQQQw _. "????9VWaamQWV???" a j/ ]QQf jQQQQQQ
QQQQQQw,"4QQQQQQm,-$Qa ???4F jQQQQQwc <aaas _aaaaa 4QW ]E )WQ`=QQQQQQQ
QQQQQQWQ/ $QQQQQQQa ?H ]Wwa, ???9WWWh dQWWW,=QWWU? ?! )WQ ]QQQQQQQ
QQQQQQQQQc-QWQQQQQW6, QWQWQQQk <c jWQ ]QQQQQQQ
QQQQQQQQQQ,"$WQQWQQQQg,."?QQQQ'.mQQQmaa,., . .; QWQ.]QQQQQQQ
QQQQQQQQQWQa ?$WQQWQQQQQa,."?( mQQQQQQW[:QQQQm[ ammF jy! j( } jQQQ(:QQQQQQQ
QQQQQQQQQQWWma "9gw?9gdB?QQwa, -??T$WQQ;:QQQWQ ]WWD _Qf +?! _jQQQWf QQQQQQQ
QQQQQQQQQQQQQQQws "Tqau?9maZ?WQmaas,, --~-- --- . _ssawmQQQQQQk 3QQQQWQ
QQQQQQQQQQQQQQQQWQga,-?9mwad?1wdT9WQQQQQWVVTTYY?YTVWQQQQWWD5mQQPQQQ ]QQQQQQ
QQQQQQQWQQQQQQQQQQQWQQwa,-??$QwadV}<wBHHVHWWBHHUWWBVTTTV5awBQQD6QQQ ]QQQQQQ
QQQQQQQQQQQQQQQQQQQQQQWWQQga,-"9$WQQmmwwmBUUHTTVWBWQQQQWVT?96aQWQQQ ]QQQQQQ
QQQQQQQQQQWQQQQWQQQQQQQQQQQWQQma,-?9$QQWWQQQQQQQWmQmmmmmQWQQQQWQQW(.yQQQQQW
QQQQQQQQQQQQQWQQQQQQWQQQQQQQQQQQQQga%,. -??9$QQQQQQQQQQQWQQWQQV? sWQQQQQQQ
QQQQQQQQQWQQQQQQQQQQQQQQWQQQQQQQQQQQWQQQQmywaa,;~^"!???????!^`_saQWWQQQQQQQ
QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQWWWWQQQQQmwywwwwwwmQQWQQQQQQQQQQQ
QQQQQQQWQQQWQQQQQQWQQQWQQQQQWQQQQQQQQQQQQQQQQWQQQQQWQQQWWWQQQQQQQQQQQQQQQWQ
dang
Executing binary
I have finally made a lateral movement to the tom
user who is part of the admin
group
As the tom
user, I can now execute the binary
tom@node:~$ /usr/local/bin/backup
tom@node:~$
I executed the binary, but it doesn’t seem to do anything. I also kept the pspy running in the back to capture if there is anything, but nothing returned
When I checked it with strings command there were a series of commands as well as ASCII artworks getting printed out. None of that is happening.
tom@node:/dev/shm$ ltrace backup ltrace backup
ltrace backup
__libc_start_main(0x80489fd, 1, 0xffe37734, 0x80492c0 <unfinished ...>
geteuid() = 1000
setuid(1000) = 0
exit(1 <no return ...>
+++ exited (status 1) +++
- The first line of the output is the entry point of the binary and it is calling the
__libc_start_main
function with a few arguments- The first argument,
0x80489fd
, is the address of themain
function in the binary. - The second argument,
1
, is the argument count passed to themain
function. - The third argument,
0xffe37734
, is the dynamic address of the argument vector passed to themain
function. - The fourth argument,
0x80492c0
, is the address of the initialization function of the program.
- The first argument,
- The second line,
geteuid() = 1000
, is a call to thegeteuid
function which is a function provided by the C library that returns the effective user ID of the current process, in this case it returned 1000 (tom
) - The third line,
setuid(1000) = 0
, is a call to thesetuid
function provided by the C library to execute asroot
Already Saw it
I realized that this is no ordinary binary
I can check the app.js
file agian.
The binary is executed with 3 arguments
This must be
backup_key
, which must be supplied as the 2nd argument
I am not sure what the -q
flag does but I will attempt to execute the binary again.
tom@node:/dev/shm$ backup -q 45fac180e9eee72f4fd2d9386ea7033e52b7c740afc3d98a8d0230167104d474 /tmp/tmp
UEsDBAoAAAAAAFwXM1YAAAAAAAAAAAAAAAAIABwAdG1wL3RtcC9VVAkAA/CxyGPwschjdXgLAAEE6QMAAATpAwAAUEsDBAoACQAAAFwXM1ZHoKhtFwAAAAsAAAAQABwAdG1wL3RtcC90ZXN0LnR4dFVUCQAD8LHIY/CxyGN1eAsAAQTpAwAABOkDAABU3vMN405P/7uC4r4C6RMh8aehqg/V5VBLBwhHoKhtFwAAAAsAAABQSwECHgMKAAAAAABcFzNWAAAAAAAAAAAAAAAACAAYAAAAAAAAABAA/UEAAAAAdG1wL3RtcC9VVAUAA/CxyGN1eAsAAQTpAwAABOkDAABQSwECHgMKAAkAAABcFzNWR6CobRcAAAALAAAAEAAYAAAAAAABAAAAtIFCAAAAdG1wL3RtcC90ZXN0LnR4dFVUBQAD8LHIY3V4CwABBOkDAAAE6QMAAFBLBQYAAAAAAgACAKQAAACzAAAAAAA=
It printed out a base64 string, which is supposed to be the archived /tmp/tmp
tom@node:/dev/shm$ echo 'testing...' > /tmp/tmp/test.txt
Continuing the test by creating a test file with some content in it
tom@node:/dev/shm$ backup -q 45fac180e9eebackup -q 45fac180e9eee72f4fd2d9386ea7033e52b7c740afc3d98a8d0230167104d474 /tmp/tmp | base64 -d > test.zip
Using the same technique, I will archive the /tmp/tmp
directory and save the decoded output to test.zip
tom@node:/dev/shm$ unzip test.zip unzip test.zip
unzip test.zip
archive: test.zip
creating: tmp/tmp/
[test.zip] tmp/tmp/test.txt password: magicword
extracting: tmp/tmp/test.txt
tom@node:/dev/shm$ cat tmp/tmp/test.txcat tmp/tmp/test.txt
cat tmp/tmp/test.txt
testing...
It works! While I figured out how the binary function, I still need to find a way to exploit it
Buffer Overflow
I couldn’t figure it out
tom@node:/dev/shm$ backup -q "" $(python -c 'print("A"*2000)')
Segmentation fault (core dumped)
Apparently the buffer overflow vulnerability exists in the 3rd argument ONLY IF the 2nd argument is empty string
So I guess that I would need to open this up..