I say cap. You say rpm. I cap your rpm!
First things first, we need to understand something about how rpm’s work. When installing a rpm you are root. Your rpm is root. Sometimes you’ll have a new application that you’ve setup using capistrano scripts. You try to explain to your hosting company the benefits of capistrano, but they refuse to listen… They leave you no choice. You don’t have time to rethink all your installation scripts nor would it be practical to maintain to different sets of deployment code. Here’s a pretty simple work around, making use of capistrano’s recent introduction of a local cache and some simple shell scripts to toggle sshd configurations.
rootkit.spec
Summary: Test rooting
Name: rootkit
Version: 1
Release: 1
Source0: %{name}-%{version}.tar.gz
Group: root
License: /root/.ssh/known_hosts MIT
Buildroot: %{_tmppath}/%{name}
ExclusiveArch: i386 x86_64
Requires: bash
AutoReqProv: no
%description
test logging in as root temporary to install
%prep
%setup -q
%build
mkdir -p $RPM_BUILD_ROOT/tmp/root_test
cp -r ./* $RPM_BUILD_ROOT/tmp/root_test
%install
%clean
%post
sudo su -
whoami
rollback() {
cp /etc/ssh/sshd_config.bak /etc/ssh/sshd_config
cp /etc/ssh/ssh_config.bak /etc/ssh/ssh_config
/sbin/service sshd restart
if [ -e /root/.ssh/authorized_keys2.bak ]; then
cp /root/.ssh/authorized_keys2.bak /root/.ssh/authorized_keys2
else
rm /root/.ssh/authorized_keys2
fi
rm /root/.ssh/tmp_root_keys
rm /root/.ssh/tmp_root_keys.pub
}
# backup all configs
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
cp /etc/ssh/ssh_config /etc/ssh/ssh_config.bak
# only backup this key file if it exists
if [ -e /root/.ssh/authorized_keys2 ]; then
echo "Backup /root/.ssh/authorized_keys2"
cp /root/.ssh/authorized_keys2 /root/.ssh/authorized_keys2.bak
fi
# setup a rollback hook to reset our ssh mods
trap rollback INT TERM EXIT
# now setup our stricter yet looser ssh configs
cat /tmp/root_test/temp_sshd_config > /etc/ssh/sshd_config
cat /tmp/root_test/temp_sshd_config > /etc/ssh/sshd_config
# restart the sshd
/sbin/service sshd restart
# setup ssh keys to use for connecting
mkdir -p /root/.ssh/
chmod 700 /root/.ssh
ssh-keygen -t dsa -P '' -f /root/.ssh/tmp_root_keys
cat /root/.ssh/tmp_root_keys.pub >> /root/.ssh/authorized_keys2
chmod 600 /root/.ssh/*
# run our test
ssh -o "VerifyHostKeyDNS ask" -i /root/.ssh/tmp_root_keys localhost -C "ruby /tmp/root_test/test.rb"
# trap should execute our rollback here
%files
%defattr(-,root,root)
/tmp/root_test/test.rb
/tmp/root_test/rootkit.spec
/tmp/root_test/README
/tmp/root_test/temp_sshd_config
/tmp/root_test/temp_ssh_config
Now there is some trickier going on here with the ssh keys. This is handled in the ssh_config
Host *
StrictHostKeyChecking no
VerifyHostKeyDNS no
GSSAPIAuthentication yes
ForwardX11Trusted no
SendEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
SendEnv LC_IDENTIFICATION LC_ALL
Next, we swap in our temporary sshd_config to make sure private/public key authentication is enabled just the way we like.
Protocol 2
PubkeyAuthentication yes
ChallengeResponseAuthentication no
GSSAPIAuthentication yes
GSSAPICleanupCredentials yes
UsePAM yes
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL
X11Forwarding no
Subsystem sftp /usr/libexec/openssh/sftp-server
Finally, we restore the system to it’s original defaults. So, if you ever need to cap deploy within an RPM hopefully this solution will help you out… enjoy! And yeah yeah, it’s not a rootkit just fun to think it is cause it’s running as root.

Recent Comments