28 Ekim 2010 Perşembe

Tproxied Squid Chain

Last week I examined squid webproxy code to understand how this tproxy thing works.
I realized that developers get most of tproxy code in kernel. So in user level, all you have to create a socket:
socketfd=socket(AF_UNIX, SOCK_STREAM, IPPROTO_TCP);
get its IP_TRANSPARENT(19) options set:
int val = 1;
setsockopt(socketfd, SOL_IP, IP_TRANSPARENT, (char *) &val, sizeof(int));
and bind it with required spoofing address:
bind(socketfd, (struct sockaddr *) &addr,sizeof(struct sockaddr_un));
after all of these, when you connect someones listening port, they will see your ip address as spoofed. But ofcourse you need to have your kernel compiled with TPROXY support.

Reason of why i dig this out is that, I need to run squid in tproxied chain mode on the same machine. When I made quick search the web, everyone says squid only operates in tproxied mode as long as it gets request from iptables. So how do we create a setup like [squid] --> [dansquardian] --> [squid] with tproxy? I asked this question to Amos Jeffries and he replied that they added this feature to squid 3.2 but haven't test it.

I tested this out and I can say it works like a charm.

I configured two squid named squid-1 and squid-2. Squid-1 is the initial one which gets the request from iptables redirection.

In squid-1 configuration file:
http_port 50080 tproxy
forwarded_for on
cache_peer 127.0.0.1 parent 50081 0 no-query login=*:nopassword no-netdb-exchange no-digest no-tproxy

In squid-2 configuration file:
http_port 50081 tproxy
forwarded_for on
follow_x_forwarded_for allow all
tproxy_uses_indirect_client on
I warn you to allow follow_x_forwarded_for only for necessary ones. It will cause to security leak in your setup.

You can add dansguardian process between these two squid by redirecting flow to dansguardian port with cache_peer option.

Ofcourse you also need to configure dansguardian to send requests to squid-2.

PS: You can reach how to configure other things like iptables,ebtables by this link.

27 Temmuz 2010 Salı

Wing IDE keygen

I have quite reverse engineering background but I have never tried to disassemble python bytecode. But i found it not so hard. Anyway i disassembled some files of Wing IDE to prepare this keygen. Here it is..

#!/usr/bin/python
def keygen(os,requestHash,version):
_os,v29,v28,v27,v26 = os,0,0,0,0

if(os != 'windows'):
if(os != 'macosx'):
if(os != 'linux'):
if(version == '2'):
v6,v5,v24,v25 = 123,202,97,211
elif(version == '3'):
v6,v5,v24,v25 = 127,45,209,198
else:#linux
if(version == '2'):
v6,v5,v24,v25 = 48,104,234,247
elif(version == '3'):
v6,v5,v24,v25 = 254,52,98,235
else:#macosx
if(version == '2'):
v6,v5,v24,v25 = 41,207,104,77
elif(version == '3'):
v6,v5,v24,v25 = 128,178,104,95
else:#windows
if(version == '2'):
v6,v5,v24,v25 = 142,43,201,38
elif(version == '3'):
v6,v5,v24,v25 = 23,163,2,115

v8=0
if(len(requestHash)):
while True:
v10=v29 * v6 + ord(requestHash[v8])
v29= v10 & 0xFFFFF
v8+=1
if not(v8 < len(requestHash)):break
v12=0
if(len(requestHash)):
while True:
v14= v28*v5+ord(requestHash[v12])
v28=v14 & 0xFFFFF
v12+=1
if not (v12 < len(requestHash)):break

v16 = 0
if( len(requestHash) ):
while True:
v18=v27*v24+ord(requestHash[v16])
v27=v18&0xFFFFF
v16+=1
if not (v16 < len(requestHash)):break

v20=0
if(len(requestHash)):
while True:
v22=v26*v25+ord(requestHash[v20])
v26=v22&0xFFFFF
v20+=1
if not (v20<len(requestHash)):break

pDest= "%.5X%.5X%.5X%.5X" % (v29,v28,v27,v26)
return pDest

def BaseConvert(number,fromdigits='0123456789ABCDEF',todigits='123456789ABCDEFGHJKLMNPQRTVWXY'):
x=long(0)
for digit in str(number):
x=x*len(fromdigits) + fromdigits.index(digit)

res=''
while True:
if not(x>0):break
digit= x % len(todigits)
res=todigits[digit]+res
x= x / len(todigits)
return res

if( __name__ == "__main__" ):
"""
Generates 'unlimited non-commercial open source use only' license for WingIDE
You can use it without any restrictions
"""

import random

dict='123456789ABCDEF'

lic='NN'
for x in range(18):
lic+=random.choice(dict)

print
print "WingIDE Key Generator by akdeniz"

print
print "Enter this licence id : ",lic

hashReq= raw_input("Enter request code ['XXXXX-XXXXX-XXXXX-XXXXX']: ")
if(len(hashReq)!=23):
exit(0)

version= raw_input('Enter version code [2 , 3] : ')
if not(version in ['2','3']):
exit(0)

os= raw_input("Enter os type [windows , linux , macosx] :")
if not(os in ['windows','linux','macosx']):
exit(0)

key=keygen(os,hashReq,version)
key=BaseConvert(key)
key='AXX'+key

print "Activation key : ",key

30 Eylül 2009 Çarşamba

Retrieving the "eip"...

After long period of being absent, here i am again. From now on I will try to send my posts in english and turkish according to my mood at that time. I apologise for my gramatical errors in advance :p

Anyway, while I was digging some metasploit shellcodes, i find out this strange opcodes:

D9 EE fldz
D9 74 24 F4 fnstenv byte ptr [esp-0Ch]
5B pop ebx

After little search, I find out metasploit use this opcodes for retrieving the value of "EIP".

-fldz loads current float register with zeros.
-fnstenv stores a structure about float processing unit status to given address.
-and pop pops :)

The structure includes:

24 -> fpu operand pointer selector
20 -> fpu operand pointer offset
16 -> fpu instruction pointer selector
12 -> fpu instruction pointer offset
08 -> tag word
04 -> status word
00 -> control word

So with loading the struct to [esp-0C], esp points to last executed code address on fpu which is "fldz" in this case.


Actually it does not give us the current eip but metasploit use this opcodes for first three of shellcode so they can save where the shellcode really begins.

To retrieve current eip, this kind of code can be used:

call label1
label1:
pop ebx.

19 Haziran 2009 Cuma

Sql injection bit-by-bit

Geçenlerde elime bir doküman geçti sql injection ile alakalı. Pratikte deneme fırsatım olmadı fakat yöntem olarak oldukça ilginç ve zekice bulduğumdan burada bahsetmek gereği duydum.


Öncelikle ortamdan bahsedeyim. Bir içerik yönetim sistemimiz(yazının verdiği örneğe bağlı kalmak açısından) olsun ve aşağıdaki gibi bir http request gönderdiğimizde hemen altındaki gibi cevap alıyoruz olalım.


GET http://host/getdocument.php?id=0

header: Location : http://host/documents/identity_en.pdf

GET http://host/getdocument.php?id=22

header: Location : http://host/error404.php

GET http://host/getdocument.php?id=22 UNION SELECT ‘identity’,0

header: Location : http://host/documents/identity_en.pdf

GET http://host/getdocument.php?id=22 UNION SELECT ‘identity’,1

header: Location : http://host/documents/identity_de.pdf


Basit olarak açıklamak gerekirse :

*Kullanıcı bir id belirtir,

*getdocument.php bu id ye karşılık veritabanından dosya adını ve dosya dilini ifade eden bir integer geri döndürür,

*sayfa bu verileri kullanarak bir url oluşturur ve kullanıcıyı bu url ye yönlendirir.


Yukarıdaki örnekleri incelersek, evet url sql injection a müsait fakat burada standart sql injection uygulayarak elde edebileceğimiz tek şey zaten varlığını bildiğimiz bir dökümandır.


Şimdi veritabanından gelen ikinci veri olan integer, eğer 0 ise bu url ye ‘en’ ekinin, 1 ise ‘de’ ekinin eklenmesini sağlıyor.Bunu nasıl kullanabiliriz? Bilgisayar ortamındaki her şeyin 0 ve 1 lerle ifade edilebildiğini hatırlarsak, yazı baya baya anlamlı olmaya başlıyor.


Bir sonraki örneklerde binary değer “01000001” olan ascii “A” yı kullanarak bakalım neler elde edebiliyoruz.


GET http://host/getdocument.php?id=22 UNION SELECT ‘identity’,(SELECT ASCII(‘A’) >> 7 & 1)

header: Location : http://host/documents/identity_en.pdf


GET http://host/getdocument.php?id=22 UNION SELECT ‘identity’,(SELECT ASCII(‘A’) >> 6& 1)

header: Location : http://host/documents/identity_de.pdf


Görüleceği üzere right-shift olayını 7 den 0 kadar iterate ettiğimizde elimizde sırası ile şu dosyalar olacak.:“en,de,en, en, en, en, en,de”


Buna artı olarak bir verinin boyutunu “LENGTH()” methoduyla alabildiğimizi ve bu method sonunda 32 bitlik(int) bir veri elde edebileceğimizi hatırlarsak, ne kadar iterate etmemiz gerektiği sorununu da çözmüş oluyoruz.


Sonuç olarak şöyle bir request hiçde şaşırtıcı gelmeyecektir.


GET http://host/getdocument.php?id=22 UNION SELECT ‘identity’,(SELECT LOAD_FILE(‘/etc/passwd’) >> 3300 & 1)


Geri dönen url yönlendirmelerinin değerine bakarak 3300 sayılı bitte 0 yada 1 olduğunu bulduktan sonra, değerleri bit-by-bit uç-uca eklersek ne elde edeceğimiz malum.


Bunu dosya boyutu kadar iterate edecek script yazmak çokta zor olmasa gerek.


Derdimi anlatamama ihtimaline karşı orjinal dokumanı Dosyalarım bölümüne ekliyorum.

25 Mayıs 2009 Pazartesi

Farkındamısınız?

Bu video ile Cebit fuarı kapsamındaki bir seminerde karşılaşmıştım. Yeniden karşılaşınca paylaşmak istedim.



Semineri yapan da yanlış hatırlamıyorsam Anne Skare Neilsen adında bir hanım ablamızdı.
Kişi isimlerini çoğu zaman hatırlayamasam da bu sahsın adı nedense hatırımda kalmış :) Seminer sırasında şeker dağıtmasından olsa gerek. Her ne kadar şeker alamasam da etkisi olmuş ki hatırlıyoruz demi :) Kendisi futurist imiş.(Bu ünvan ile de ilk defa o zaman karşılaşmıştım.) Ha ne diyordum video değil mi... :)

25 Nisan 2009 Cumartesi

Programatik olarak driver yükleme

Rootkitlerle veya daha genel anlamda driverlarla uğraşmış olanlar ‘sc create|start|delete|….’ komut varyasyonunun makina üzerindeki sürücüleri kontrol etmede kullanıldığını bilir. Sürekli şekilde driver yükleyip silenlerden iseniz bu yöntem can sıkmaya başlayabiliyor. Peki o zaman napalım: Bu işlemin programatik şekilde nasıl yapılacağına bakalım.

Şöyle küçük bir sınıf yazıp static fonksiyonları üzerinden işimizi halledebiliriz sanırım.

#include "windows.h"

#include "iostream"

#include "string"

#include "stdio.h"

using namespace std;

class Driver{

public:

static DWORD Install(IN LPCTSTR, IN LPCTSTR);

static DWORD Start(IN LPCTSTR);

static DWORD Open( IN LPCTSTR, HANDLE *);

static DWORD Stop(IN LPCTSTR);

static DWORD Remove(IN LPCTSTR);

};

Aşağıdaki kodu incelediğinizde de anlayacağınız üzere her bir fonksiyon öncelikle “Service Control Manager” açıyor ve onun üzerinden işini görüyor.

#include "stdafx.h"

#include "InstallDriver.h"

#include "winuser.h"

#include "stdlib.h"

DWORD Driver::Install(IN LPCTSTR DriverName, IN LPCTSTR ServiceExe){

SC_HANDLE hSCManager,hService;

TCHAR data[80];

DWORD dw=0;

hSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );

if(hSCManager==NULL)

return GetLastError();

hService = CreateService( hSCManager, // SCManager database

DriverName, // name of service

DriverName, // name to display

SERVICE_ALL_ACCESS, // desired access

SERVICE_KERNEL_DRIVER, // service type

SERVICE_DEMAND_START, // start type

SERVICE_ERROR_NORMAL, // error control type

ServiceExe, // service's binary

NULL, // no load ordering group

NULL, // no tag identifier

NULL, // no dependencies

NULL, // LocalSystem account

NULL // no password

);

if(hService==NULL){

dw=GetLastError();

CloseServiceHandle(hSCManager);

return dw;

}

CloseServiceHandle( hService );

CloseServiceHandle(hSCManager);

return dw;

}

//Sürücünün doğru bir şekilde yüklenip yüklenmediğini kontrol etmek için

DWORD Driver::Open( IN LPCTSTR DriverName, HANDLE * lphDevice )

{

TCHAR completeDeviceName[64];

HANDLE hDevice;

DWORD dw=0;

//Burada ABC ismindeki bir sürücünün \DosDevices\ABC adında bir

//sembolik link oluşturduğunu varsayıyoruz. Tabi böyle bir varsayım

//yerine QueryDosDevice komutuyla varolan sembolik linkleri çekebilirdik.

if( (GetVersion() & 0xFF) >= 5 )

wsprintf( completeDeviceName, TEXT("\\\\.\\Global\\%s"), DriverName );

else

wsprintf( completeDeviceName, TEXT("\\\\.\\%s"), DriverName );

hDevice = CreateFile( completeDeviceName,

GENERIC_READ | GENERIC_WRITE,

FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,

NULL,OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL

);

if ( hDevice == INVALID_HANDLE_VALUE)

return GetLastError();

if ( lphDevice )

*lphDevice = hDevice;

else

CloseHandle( hDevice );

return dw;

}

DWORD Driver::Start( IN LPCTSTR DriverName){

SC_HANDLE hSCManager;

SC_HANDLE hService;

BOOL ret;

DWORD dw=0;

hSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );

if(hSCManager==NULL)

return GetLastError();

hService = OpenService( hSCManager,DriverName,SERVICE_ALL_ACCESS );

if ( hService == NULL ){

dw=GetLastError();

CloseServiceHandle(hSCManager);

return dw;

}

ret = StartService( hService, 0, NULL );

dw=ret?0:GetLastError();

CloseServiceHandle( hService );

CloseServiceHandle(hSCManager);

return dw;

}

DWORD Driver::Stop(IN LPCTSTR DriverName){

SERVICE_STATUS serviceStatus;

SC_HANDLE hSCManager;

SC_HANDLE hService;

BOOL ret;

DWORD dw=0;

hSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );

if(hSCManager==NULL)

return GetLastError();

hService = OpenService( hSCManager,DriverName,SERVICE_ALL_ACCESS );

if ( hService == NULL ){

dw=GetLastError();

CloseServiceHandle(hSCManager);

return dw;

}

ret = ControlService( hService, SERVICE_CONTROL_STOP, &serviceStatus );

dw=ret?0:GetLastError();

CloseServiceHandle( hService );

CloseServiceHandle(hSCManager);

return dw;

}

DWORD Driver::Remove(IN LPCTSTR DriverName){

SC_HANDLE hSCManager;

SC_HANDLE hService;

BOOL ret;

DWORD dw=0;

hSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );

if(hSCManager==NULL)

return GetLastError();

hService = OpenService( hSCManager,DriverName,SERVICE_ALL_ACCESS );

if ( hService == NULL ){

dw=GetLastError();

CloseServiceHandle(hSCManager);

return dw;

}

ret = DeleteService( hService );

dw=ret?0:GetLastError();

CloseServiceHandle( hService );

CloseServiceHandle(hSCManager);

return dw;

}

Kullanıma örnek olarakta aşağıdaki resimdeki gibi arayüze sahip bir program yazılabilir.












Proje dosyasına Dosyalarım bölümünden erişilebilir.