Remote File Inclusion Attempts
The Report:
Chris wrote in this morning reporting: "a group from Turkey who have been trying really hard to inject this PHP exploit into my web site."
From the log snippet supplied it appears on the surface to be a Remote File Inclusion attempt. PHP applications vulnerable to such attacks allow an attacker to execute their own code on the web-server with a simple crafted request.
More information about Remote File Inclusion can be found:
en.wikipedia.org/wiki/Remote_File_Inclusion
lwn.net/Articles/203904/
The attackers attempted to include code from alganx.by.ru called r57.txt.
Passive Investigation:
We begin first with low-impact analysis with a few digs, whois' etc.
;; ANSWER SECTION:
alganx.by.ru. 9h14m49s IN A 217.16.29.51
;; AUTHORITY SECTION:
by.ru. 9h14m49s IN NS ns2.by.ru.
by.ru. 9h14m49s IN NS ns3.by.ru.
by.ru. 9h14m49s IN NS ns1.by.ru.
;; ADDITIONAL SECTION:
ns2.by.ru. 9h14m49s IN A 88.212.197.61
ns3.by.ru. 9h14m49s IN A 88.212.196.170
ns1.by.ru. 9h14m49s IN A 217.16.29.50
Maxmind's GeoIP places the IPs in Moscow. Let's see if RIPE.NET agrees...
% Information related to '217.16.29.48 - 217.16.29.55'
inetnum: 217.16.29.48 - 217.16.29.55
netname: EVERNET
descr: Free web hosting
country: RU
admin-c: amg28-ripe
tech-c: amg28-ripe
mnt-by: MASTERHOST-MNT
status: ASSIGNED PA "status:" definitions
source: RIPE # Filtered
person: Aleksei M Golubev
address: Moscow, Russia
e-mail: noc@ever.ru
remarks: phone: +7 095 7712007
phone: +7 495 7712007
remarks: fax-no: +7 095 7712007
fax-no: +7 495 7712007
mnt-by: MASTERHOST-MNT
nic-hdl: AMG28-RIPE
source: RIPE # Filtered
remarks: modified for Russian phone area changes
And also:
% Information related to '88.212.192.0 - 88.212.220.255'
inetnum: 88.212.192.0 - 88.212.220.255
netname: SKYMEDIA-NET
descr: Sky-Media Ltd. network
remarks: You aren't right!
country: RU
admin-c: SKYM-RIPE
tech-c: SKYM-RIPE
status: ASSIGNED PA "status:" definitions
mnt-by: SKYMEDIA-MNT
source: RIPE # Filtered
role: SKYMEDIA NOC
address: Sky-Media Network Operation Center
address: 9, Sushevsky Val
address: 127018 Moscow Russia
phone: +7 495 9816042
abuse-mailbox: abuse@skyme.ru
admin-c: DD5555-RIPE
admin-c: PS5555-RIPE
admin-c: SO796-RIPE
tech-c: PS5555-RIPE
tech-c: SKYM-RIPE
nic-hdl: SKYM-RIPE
mnt-by: SKYMEDIA-MNT
source: RIPE # Filtered
This leaves me with a couple of email address I can try for getting the file removed.
We continue passive investigation with a bit of googling around. With the recent malicious javascript incidents that I've been working on you can get a gauge of the extent of the distribution of the malicious links. This is different, since in RFI you'll see the code in the access logs, not as live links littered through people's blogs. In today's incident we turn up that r57.txt has been around for quite a while. One can find this being discussed as far back as 2004-- well one can find discussions about r57.txt, the file name, appearing in their access logs.
Grabbing the File
The next step is to grab a copy of r57.txt to see what it does. Using wget it is straightforward in this case. I clamscan it out of habit and it scans cleanly. Though visual inspection I can tell that this is a copy of the r57shell-- because it says so in the header. Fear my reverse engineering skillz.
So What Does this Actually Do?
Let's assume that this actually worked. How bad of a day is Chris going to have?
From simply looking at the code, I would venture to say that a compromise like this is very bad. It allows the attacker near-shell access. Depending on the permissions that PHP is running under, this could lead to a total compromise of the system.
It supports both Russian and English languages. It will talk to MySQL, Postgres, or Oracle databases.
The multi-language support exposes a lot of the codes features, from the English support definitions:
/* --------------------------------------------------------------- */
'eng_text1' =>'Executed command',
'eng_text2' =>'Execute command on server',
'eng_text3' =>'Run command',
'eng_text4' =>'Work directory',
'eng_text5' =>'Upload files on server',
'eng_text6' =>'Local file',
'eng_text7' =>'Aliases',
'eng_text8' =>'Select alias',
'eng_butt1' =>'Execute',
'eng_butt2' =>'Upload',
'eng_text9' =>'Bind port to /bin/bash',
'eng_text10'=>'Port',
'eng_text11'=>'Password for access',
'eng_butt3' =>'Bind',
'eng_text12'=>'back-connect',
'eng_text13'=>'IP',
'eng_text14'=>'Port',
'eng_butt4' =>'Connect',
'eng_text15'=>'Upload files from remote server',
'eng_text16'=>'With',
'eng_text17'=>'Remote file',
'eng_text18'=>'Local file',
'eng_text19'=>'Exploits',
'eng_text20'=>'Use',
'eng_text21'=>' New name',
'eng_text22'=>'datapipe',
'eng_text23'=>'Local port',
'eng_text24'=>'Remote host',
'eng_text25'=>'Remote port',
'eng_text26'=>'Use',
'eng_butt5' =>'Run',
'eng_text28'=>'Work in safe_mode',
'eng_text29'=>'ACCESS DENIED',
'eng_butt6' =>'Change',
'eng_text30'=>'Cat file',
'eng_butt7' =>'Show',
'eng_text31'=>'File not found',
'eng_text32'=>'Eval PHP code',
'eng_text33'=>'Test bypass open_basedir with cURL functions',
'eng_butt8' =>'Test',
'eng_text34'=>'Test bypass safe_mode with include function',
'eng_text35'=>'Test bypass safe_mode with load file in mysql',
'eng_text36'=>'Database',
'eng_text37'=>'Login',
'eng_text38'=>'Password',
'eng_text39'=>'Table',
'eng_text40'=>'Dump database table',
'eng_butt9' =>'Dump',
'eng_text41'=>'Save dump in file',
'eng_text42'=>'Edit files',
'eng_text43'=>'File for edit',
'eng_butt10'=>'Save',
'eng_text44'=>'Can\'t edit file! Only read access!',
'eng_text45'=>'File saved',
'eng_text46'=>'Show phpinfo()',
'eng_text47'=>'Show variables from php.ini',
'eng_text48'=>'Delete temp files',
'eng_butt11'=>'Edit file',
'eng_text49'=>'Delete script from server',
'eng_text50'=>'View cpu info',
'eng_text51'=>'View memory info',
'eng_text52'=>'Find text',
'eng_text53'=>'In dirs',
'eng_text54'=>'Find text in files',
'eng_butt12'=>'Find',
'eng_text55'=>'Only in files',
'eng_text56'=>'Nothing :(',
'eng_text57'=>'Create/Delete File/Dir',
'eng_text58'=>'name',
'eng_text59'=>'file',
'eng_text60'=>'dir',
'eng_butt13'=>'Create/Delete',
'eng_text61'=>'File created',
'eng_text62'=>'Dir created',
'eng_text63'=>'File deleted',
'eng_text64'=>'Dir deleted',
'eng_text65'=>'Create',
'eng_text66'=>'Delete',
'eng_text67'=>'Chown/Chgrp/Chmod',
'eng_text68'=>'Command',
'eng_text69'=>'param1',
'eng_text70'=>'param2',
'eng_text71'=>"Second commands param is:\r\n- for CHOWN - name of new owner or UID\r\n- for CHGRP - group name or GID\r\n- for CHMOD - 0777, 0755...",
'eng_text72'=>'Text for find',
'eng_text73'=>'Find in folder',
'eng_text74'=>'Find in files',
'eng_text75'=>'* you can use regexp',
'eng_text76'=>'Search text in files via find',
'eng_text77'=>'Show database structure',
'eng_text78'=>'show tables',
'eng_text79'=>'show columns',
'eng_text80'=>'Type',
'eng_text81'=>'Net',
'eng_text82'=>'Databases',
'eng_text83'=>'Run SQL query',
'eng_text84'=>'SQL query',
);
Some of the examinations it performs on the system (also straight from the code):
'find suid files'=>'find / -type f -perm -04000 -ls',
'find suid files in current dir'=>'find . -type f -perm -04000 -ls',
'find sgid files'=>'find / -type f -perm -02000 -ls',
'find sgid files in current dir'=>'find . -type f -perm -02000 -ls',
'find config.inc.php files'=>'find / -type f -name config.inc.php',
'find config.inc.php files in current dir'=>'find . -type f -name config.inc.php',
'find config* files'=>'find / -type f -name "config*"',
'find config* files in current dir'=>'find . -type f -name "config*"',
'find all writable files'=>'find / -type f -perm -2 -ls',
'find all writable files in current dir'=>'find . -type f -perm -2 -ls',
'find all writable directories'=>'find / -type d -perm -2 -ls',
'find all writable directories in current dir'=>'find . -type d -perm -2 -ls',
'find all writable directories and files'=>'find / -perm -2 -ls',
'find all writable directories and files in current dir'=>'find . -perm -2 -ls',
'find all service.pwd files'=>'find / -type f -name service.pwd',
'find service.pwd files in current dir'=>'find . -type f -name service.pwd',
'find all .htpasswd files'=>'find / -type f -name .htpasswd',
'find .htpasswd files in current dir'=>'find . -type f -name .htpasswd',
'find all .bash_history files'=>'find / -type f -name .bash_history',
'find .bash_history files in current dir'=>'find . -type f -name .bash_history',
'find all .mysql_history files'=>'find / -type f -name .mysql_history',
'find .mysql_history files in current dir'=>'find . -type f -name .mysql_history',
'find all .fetchmailrc files'=>'find / -type f -name .fetchmailrc',
'find .fetchmailrc files in current dir'=>'find . -type f -name .fetchmailrc',
'list file attributes on a Linux second extended file system'=>'lsattr -va',
'show opened ports'=>'netstat -an | grep -i listen',
You can see it's looking for vulnerable points in system (suid files with potential vulnerabilities of their own, writable directories to use, etc.) It also grabs passwords and hashes for offline attacks.
It has shellcode to allow the attacker to run a bindshell on the compromised server, or to open up a reverse shell to an attacker's system.
It reports on system monitoring statistics, so you don't place too much load on a system with your antics. It helps the attacker determine what tools (wget, fetch, lynx, links, curl, etc.) on on the system to pull down additional tools/file.
So if we assume that PHP isn't running uid 0 already, the attacker is able to investigate the filesystem on the server, and likely upload and execute any code they wish. Which means that root-access isn't far off.
This would end up being a very bad day for anyone to have this happen to their system.
Vulnerable Systems
Remote File Inclusion is a sub-set of Input Validation Attacks. It is a fairly common (sadly) vulnerability. Now many weeks go by where there is not an announced RFI in some PHP application or other. There's over 800 examples in Secunia's vulnerability database. Register_globals is big entry point these, and it's common hardening advice to disable it.
www.hardened-php.net/advisory_202005.79.html
Quick fix from fellow-handler Swa:
"In the php.ini:
Change
register_globals = On
into
register_globals = Off
(or add the latter)
While at it, change:
allow_url_fopen = On
into:
allow_url_fopen = Off
This latter disables remote includes
You'll likely need to restart the webserver after this for the updates to take effect."
UPDATE:
As Stephan Esser wisely points out: the above quick-fix will not block all RFI attempts. He provides a hardening-patch and Suhosin which raise the bar a bit higher for the attacker.
Previous Incidents
r57shell was mentioned in an earlier diary.
-KL
Chris wrote in this morning reporting: "a group from Turkey who have been trying really hard to inject this PHP exploit into my web site."
From the log snippet supplied it appears on the surface to be a Remote File Inclusion attempt. PHP applications vulnerable to such attacks allow an attacker to execute their own code on the web-server with a simple crafted request.
More information about Remote File Inclusion can be found:
en.wikipedia.org/wiki/Remote_File_Inclusion
lwn.net/Articles/203904/
The attackers attempted to include code from alganx.by.ru called r57.txt.
Passive Investigation:
We begin first with low-impact analysis with a few digs, whois' etc.
;; ANSWER SECTION:
alganx.by.ru. 9h14m49s IN A 217.16.29.51
;; AUTHORITY SECTION:
by.ru. 9h14m49s IN NS ns2.by.ru.
by.ru. 9h14m49s IN NS ns3.by.ru.
by.ru. 9h14m49s IN NS ns1.by.ru.
;; ADDITIONAL SECTION:
ns2.by.ru. 9h14m49s IN A 88.212.197.61
ns3.by.ru. 9h14m49s IN A 88.212.196.170
ns1.by.ru. 9h14m49s IN A 217.16.29.50
Maxmind's GeoIP places the IPs in Moscow. Let's see if RIPE.NET agrees...
% Information related to '217.16.29.48 - 217.16.29.55'
inetnum: 217.16.29.48 - 217.16.29.55
netname: EVERNET
descr: Free web hosting
country: RU
admin-c: amg28-ripe
tech-c: amg28-ripe
mnt-by: MASTERHOST-MNT
status: ASSIGNED PA "status:" definitions
source: RIPE # Filtered
person: Aleksei M Golubev
address: Moscow, Russia
e-mail: noc@ever.ru
remarks: phone: +7 095 7712007
phone: +7 495 7712007
remarks: fax-no: +7 095 7712007
fax-no: +7 495 7712007
mnt-by: MASTERHOST-MNT
nic-hdl: AMG28-RIPE
source: RIPE # Filtered
remarks: modified for Russian phone area changes
And also:
% Information related to '88.212.192.0 - 88.212.220.255'
inetnum: 88.212.192.0 - 88.212.220.255
netname: SKYMEDIA-NET
descr: Sky-Media Ltd. network
remarks: You aren't right!
country: RU
admin-c: SKYM-RIPE
tech-c: SKYM-RIPE
status: ASSIGNED PA "status:" definitions
mnt-by: SKYMEDIA-MNT
source: RIPE # Filtered
role: SKYMEDIA NOC
address: Sky-Media Network Operation Center
address: 9, Sushevsky Val
address: 127018 Moscow Russia
phone: +7 495 9816042
abuse-mailbox: abuse@skyme.ru
admin-c: DD5555-RIPE
admin-c: PS5555-RIPE
admin-c: SO796-RIPE
tech-c: PS5555-RIPE
tech-c: SKYM-RIPE
nic-hdl: SKYM-RIPE
mnt-by: SKYMEDIA-MNT
source: RIPE # Filtered
This leaves me with a couple of email address I can try for getting the file removed.
We continue passive investigation with a bit of googling around. With the recent malicious javascript incidents that I've been working on you can get a gauge of the extent of the distribution of the malicious links. This is different, since in RFI you'll see the code in the access logs, not as live links littered through people's blogs. In today's incident we turn up that r57.txt has been around for quite a while. One can find this being discussed as far back as 2004-- well one can find discussions about r57.txt, the file name, appearing in their access logs.
Grabbing the File
The next step is to grab a copy of r57.txt to see what it does. Using wget it is straightforward in this case. I clamscan it out of habit and it scans cleanly. Though visual inspection I can tell that this is a copy of the r57shell-- because it says so in the header. Fear my reverse engineering skillz.
So What Does this Actually Do?
Let's assume that this actually worked. How bad of a day is Chris going to have?
From simply looking at the code, I would venture to say that a compromise like this is very bad. It allows the attacker near-shell access. Depending on the permissions that PHP is running under, this could lead to a total compromise of the system.
It supports both Russian and English languages. It will talk to MySQL, Postgres, or Oracle databases.
The multi-language support exposes a lot of the codes features, from the English support definitions:
/* --------------------------------------------------------------- */
'eng_text1' =>'Executed command',
'eng_text2' =>'Execute command on server',
'eng_text3' =>'Run command',
'eng_text4' =>'Work directory',
'eng_text5' =>'Upload files on server',
'eng_text6' =>'Local file',
'eng_text7' =>'Aliases',
'eng_text8' =>'Select alias',
'eng_butt1' =>'Execute',
'eng_butt2' =>'Upload',
'eng_text9' =>'Bind port to /bin/bash',
'eng_text10'=>'Port',
'eng_text11'=>'Password for access',
'eng_butt3' =>'Bind',
'eng_text12'=>'back-connect',
'eng_text13'=>'IP',
'eng_text14'=>'Port',
'eng_butt4' =>'Connect',
'eng_text15'=>'Upload files from remote server',
'eng_text16'=>'With',
'eng_text17'=>'Remote file',
'eng_text18'=>'Local file',
'eng_text19'=>'Exploits',
'eng_text20'=>'Use',
'eng_text21'=>' New name',
'eng_text22'=>'datapipe',
'eng_text23'=>'Local port',
'eng_text24'=>'Remote host',
'eng_text25'=>'Remote port',
'eng_text26'=>'Use',
'eng_butt5' =>'Run',
'eng_text28'=>'Work in safe_mode',
'eng_text29'=>'ACCESS DENIED',
'eng_butt6' =>'Change',
'eng_text30'=>'Cat file',
'eng_butt7' =>'Show',
'eng_text31'=>'File not found',
'eng_text32'=>'Eval PHP code',
'eng_text33'=>'Test bypass open_basedir with cURL functions',
'eng_butt8' =>'Test',
'eng_text34'=>'Test bypass safe_mode with include function',
'eng_text35'=>'Test bypass safe_mode with load file in mysql',
'eng_text36'=>'Database',
'eng_text37'=>'Login',
'eng_text38'=>'Password',
'eng_text39'=>'Table',
'eng_text40'=>'Dump database table',
'eng_butt9' =>'Dump',
'eng_text41'=>'Save dump in file',
'eng_text42'=>'Edit files',
'eng_text43'=>'File for edit',
'eng_butt10'=>'Save',
'eng_text44'=>'Can\'t edit file! Only read access!',
'eng_text45'=>'File saved',
'eng_text46'=>'Show phpinfo()',
'eng_text47'=>'Show variables from php.ini',
'eng_text48'=>'Delete temp files',
'eng_butt11'=>'Edit file',
'eng_text49'=>'Delete script from server',
'eng_text50'=>'View cpu info',
'eng_text51'=>'View memory info',
'eng_text52'=>'Find text',
'eng_text53'=>'In dirs',
'eng_text54'=>'Find text in files',
'eng_butt12'=>'Find',
'eng_text55'=>'Only in files',
'eng_text56'=>'Nothing :(',
'eng_text57'=>'Create/Delete File/Dir',
'eng_text58'=>'name',
'eng_text59'=>'file',
'eng_text60'=>'dir',
'eng_butt13'=>'Create/Delete',
'eng_text61'=>'File created',
'eng_text62'=>'Dir created',
'eng_text63'=>'File deleted',
'eng_text64'=>'Dir deleted',
'eng_text65'=>'Create',
'eng_text66'=>'Delete',
'eng_text67'=>'Chown/Chgrp/Chmod',
'eng_text68'=>'Command',
'eng_text69'=>'param1',
'eng_text70'=>'param2',
'eng_text71'=>"Second commands param is:\r\n- for CHOWN - name of new owner or UID\r\n- for CHGRP - group name or GID\r\n- for CHMOD - 0777, 0755...",
'eng_text72'=>'Text for find',
'eng_text73'=>'Find in folder',
'eng_text74'=>'Find in files',
'eng_text75'=>'* you can use regexp',
'eng_text76'=>'Search text in files via find',
'eng_text77'=>'Show database structure',
'eng_text78'=>'show tables',
'eng_text79'=>'show columns',
'eng_text80'=>'Type',
'eng_text81'=>'Net',
'eng_text82'=>'Databases',
'eng_text83'=>'Run SQL query',
'eng_text84'=>'SQL query',
);
Some of the examinations it performs on the system (also straight from the code):
'find suid files'=>'find / -type f -perm -04000 -ls',
'find suid files in current dir'=>'find . -type f -perm -04000 -ls',
'find sgid files'=>'find / -type f -perm -02000 -ls',
'find sgid files in current dir'=>'find . -type f -perm -02000 -ls',
'find config.inc.php files'=>'find / -type f -name config.inc.php',
'find config.inc.php files in current dir'=>'find . -type f -name config.inc.php',
'find config* files'=>'find / -type f -name "config*"',
'find config* files in current dir'=>'find . -type f -name "config*"',
'find all writable files'=>'find / -type f -perm -2 -ls',
'find all writable files in current dir'=>'find . -type f -perm -2 -ls',
'find all writable directories'=>'find / -type d -perm -2 -ls',
'find all writable directories in current dir'=>'find . -type d -perm -2 -ls',
'find all writable directories and files'=>'find / -perm -2 -ls',
'find all writable directories and files in current dir'=>'find . -perm -2 -ls',
'find all service.pwd files'=>'find / -type f -name service.pwd',
'find service.pwd files in current dir'=>'find . -type f -name service.pwd',
'find all .htpasswd files'=>'find / -type f -name .htpasswd',
'find .htpasswd files in current dir'=>'find . -type f -name .htpasswd',
'find all .bash_history files'=>'find / -type f -name .bash_history',
'find .bash_history files in current dir'=>'find . -type f -name .bash_history',
'find all .mysql_history files'=>'find / -type f -name .mysql_history',
'find .mysql_history files in current dir'=>'find . -type f -name .mysql_history',
'find all .fetchmailrc files'=>'find / -type f -name .fetchmailrc',
'find .fetchmailrc files in current dir'=>'find . -type f -name .fetchmailrc',
'list file attributes on a Linux second extended file system'=>'lsattr -va',
'show opened ports'=>'netstat -an | grep -i listen',
You can see it's looking for vulnerable points in system (suid files with potential vulnerabilities of their own, writable directories to use, etc.) It also grabs passwords and hashes for offline attacks.
It has shellcode to allow the attacker to run a bindshell on the compromised server, or to open up a reverse shell to an attacker's system.
It reports on system monitoring statistics, so you don't place too much load on a system with your antics. It helps the attacker determine what tools (wget, fetch, lynx, links, curl, etc.) on on the system to pull down additional tools/file.
So if we assume that PHP isn't running uid 0 already, the attacker is able to investigate the filesystem on the server, and likely upload and execute any code they wish. Which means that root-access isn't far off.
This would end up being a very bad day for anyone to have this happen to their system.
Vulnerable Systems
Remote File Inclusion is a sub-set of Input Validation Attacks. It is a fairly common (sadly) vulnerability. Now many weeks go by where there is not an announced RFI in some PHP application or other. There's over 800 examples in Secunia's vulnerability database. Register_globals is big entry point these, and it's common hardening advice to disable it.
www.hardened-php.net/advisory_202005.79.html
Quick fix from fellow-handler Swa:
"In the php.ini:
Change
register_globals = On
into
register_globals = Off
(or add the latter)
While at it, change:
allow_url_fopen = On
into:
allow_url_fopen = Off
This latter disables remote includes
You'll likely need to restart the webserver after this for the updates to take effect."
UPDATE:
As Stephan Esser wisely points out: the above quick-fix will not block all RFI attempts. He provides a hardening-patch and Suhosin which raise the bar a bit higher for the attacker.
Previous Incidents
r57shell was mentioned in an earlier diary.
-KL
Keywords:
0 comment(s)
×
Diary Archives
Comments