Turkhackteam.net/org - Turkish Hacking & Security Platform  
Geri git   Turkhackteam.net/org - Turkish Hacking & Security Platform >
Information Technology’s
> Network

Network Network İle İlgili Bölümümüz ...



X-Ray Görüşünden Torsocks .knuth

Network

Yeni Konu aç Cevapla
 
Seçenekler
Alt bir Hafta önce   #1
  • Albay
  • Üye Bilgileri
Üyelik tarihi
07/2018
Nereden
.k
Mesajlar
4
Konular
1


  
X-Ray Görüşünden Torsocks .knuth



X-Ray Görüşünden Torsocks .knuth

.giriş
Şu sektörde olmamızın bir getirisi olaraktan yaşamımızın bir parçası haline gelen yazılımların oluşturulma, geliştirilme sürecinde yatan ayrıntılar, uygulanan method ve uygulama içerisinde izlerine rastlanan tekniklerin keşfi; kişinin bu vazgeçilmesi anlamasında önemli bir yere sahiptir. Kullandığımız bu yazılımlar, yazarı tarafından birtakım işlemleri gerçekleştirmek maksadıyla oluşturulmuşlardır. Bu işlemlerin aslen ne olduğunu anlamaksızın üstünkörü kullanmak, içerisinde fizik yasalarına aykırı gizemli olaylar döndüğüne kanaat getirmek kişiye bir şey katmaz, sadece başta da belirttiğim üzere "yaşamının bir parçası" olur. Onsuz yapamaz, onsuz hareket edemez ve ona bağlanır. Makul olan, arka planında dönen dolapları gün yüzüne çıkarıp kendini bu bağımlılıktan alıkoymaktır. Ne yazık ki sadece kullanıyor ve onları vazgeçilmez kılmaya diretiyoruz, kavramaya çalışmıyoruz, anlamak için çaba sarf etmiyoruz.

Tüm bu sebeplerden ötürü, "X-Ray Görüşünden" başlığı altında yazılımların işlevsel fonksiyonlarını gün yüzüne çıkartmayı hedefleyen bir dizi oluşturmayı uygun gördüm. Kişiye, sıkça kullandığı yazılımların ve hatta donanımların gün gibi ortada olan gizemlerini anlatmak maksadıyla bu tarz bir girişimde bulundum. Bugün ele alacağımız yazılım, başlıktan da anlayabileceğiniz üzere "torsocks" olacaktır. Şimdiden okuduğunuz için teşekkür ediyorum.


.torsocks
Yazılım ile ilgili açıklamayı, UNIX türevi işletim sistemlerinde ve Linux dağıtımlarında yer edinmiş, kullanıcının kılavuzu niteliğinde olan dokümanların barındırıldığı "man" sayfalarından alıntılayarak yapmak istiyorum. Dokümanı niteliğinde olduğu araçların niteliklerine göre kategorize edilmiş bu sayfalardan, bizim ihtiyacımız olan "kullanıcı komutları"nı barındıran birinci sektör ile "yönetimsel, ayrıcalıklı komutlar"ın barındırıldığı sekizinci sektör olacaktır (ref. man man). Dokümanlar bünyesinde torsocks(1) der ki,
Alıntı:
[EN] torsocks (1) - Shell wrapper to simplify the use of the torsocks(8) library to transparently allow an application to use a SOCKS proxy. Basically a renamed, patched tsocks.
[TR] torsocks (1) - torsocks(8) kütüphanesini, uygulamanın net bir biçimde SOCKS proxy kullanımını sağlamak maksadıyla basite indirgeyen kabuk betiğidir. Kısaca yeniden isimlendirilmiş, yamalanmış "tsocks" olarak da isimlendirilebilir.
Ve de, torsocks(1)'de de ismi geçen torsocks(8)'e de bakacak olursak,
Alıntı:
[EN] torsocks (8) - Library for intercepting outgoing network connections and redirecting them through a SOCKS server.
[TR] torsocks (8) - Giden ağ bağlantılarını yakalayan ve onları bir SOCKS sunucusuna yönlendiren kütüphane.
olarak isimlendirildiklerini görebiliriz (ref. https://linux.die.net/man/8/torsocks, https://linux.die.net/man/1/torsocks). Daha detaylı bilgi, henüz giriş yapmadan evvel okumak isteyenler için "man" sayfalarında barındırılmaktadır. Kısaca "torsocks", giden ağ bağlantılarını bir biçimde manipüle ederekten onları herhangi bir proxy sunucusuna yönlendiren bir yazılım imiş hepimizin bildiği üzere. Asıl sorun şu, bunu nasıl gerçekleştiriyor -konumuzun açılma sebebi de işte tam olarak bu soruyu cevaplandırmaktır.

"https://gitweb.torproject.org/torsocks.git/tree/" adreslemesinde uygulamanın dizinine erişim mümkündür, ayrıyeten ileriki aşamalarda analizimizi kolaylaştırması maksadıyla ilgili dizinin ağaç diyagramını da şöyle bırakmak istiyorum,
Kod:
torsocks-master> Tree /F /A | Where-Object -FilterScript {($_ -notlike "*config*") -and ($_ -notlike "*test_*") -and ($_ -notlike "*Makefile*")}
C:.
|   .gitignore
|   .travis.yml
|   autogen.sh
|   ChangeLog
|   gpl-2.0.txt
|   INSTALL
|   LICENSE
|   README.md
|
+---doc
|   |   torsocks.1
|   |   torsocks.8
|   |   torsocks.conf
|   |   torsocks.conf.5
|   |
|   +---notes
|   |       DEBUG
|   |
|   +---proposals
|   |       01-Thread-safe-design.txt
|   |
|   \---socks
|           socks-extensions.txt
|           SOCKS5
|
+---extras
|       torsocks-bash_completion
|       torsocks-zsh_completion
|
+---src
|   |
|   +---bin
|   |       torsocks.in
|   |
|   +---common
|   |       compat.c
|   |       compat.h
|   |       connection.c
|   |       connection.h
|   |       defaults.h
|   |       ht.h
|   |       log.c
|   |       log.h
|   |       macros.h
|   |       onion.c
|   |       onion.h
|   |       ref.h
|   |       socks5.c
|   |       socks5.h
|   |       utils.c
|   |       utils.h
|   |
|   \---lib
|           accept.c
|           close.c
|           connect.c
|           execve.c
|           exit.c
|           fclose.c
|           getaddrinfo.c
|           gethostbyname.c
|           getpeername.c
|           listen.c
|           recv.c
|           sendto.c
|           socket.c
|           socketpair.c
|           syscall.c
|           torsocks.c
|           torsocks.h
|
\---tests
    |   helpers.c
    |   helpers.h
    |   tap-driver.sh
    |
    \---utils
        |   fixtures.h
        |
        \---tap
                tap.c
                tap.h
                tap.sh
İhtiyacımız olmayan yahut çıktıda yer alması bir şey ifade etmeyecek dizinler filtrelenmiştir. İlgileneceğimiz dosyalar, sonuç itibariyle daha çok "src/" dizininde barınan dosyalar olacaktır. Her şeyden evvel, Autoconf kaynak dosyası olan ve kök dizinde bulunan "configure.ac" yapısına göz atmalı, ilgili yapı yazılımın derlenmesi aşamasında kullanılması icap eden "configure" dosyasının oluşturulması esnasında kullanılacaktır. Dosya bünyesinde derleyici argümanlarından linker, yani bilgisayar terminolojisinde derleyicinin meydana getirdiği tüm yazılımları tek parçaya getiren aracın konfigürasyonuna kadar birçok bilgi ile platforma ilişkin gerçekleştirilmesi gereken kontrollerin detayları, tanımlı makrolar ve ifadeler aracılığıyla barındırılmaktadır. "autoconf", "automake" ve bu araçların "Makefile" oluşturulması adına izledikleri yola da, şu diyagramda kabaca yer verilmiştir,


.diyagram


.\configure.ac
Kod:
AX_CHECK_COMPILE_FLAG([-fPIE],[CFLAGS="$CFLAGS -fPIE"],[],[])
AX_CHECK_COMPILE_FLAG([-fwrapv],[CFLAGS="$CFLAGS -fwrapv"],[],[])
AX_CHECK_COMPILE_FLAG([--param ssp-buffer-size=1],
	[CFLAGS="$CFLAGS --param ssp-buffer-size=1"],[],[])
AX_CHECK_COMPILE_FLAG([-fstack-protector-all],
	[CFLAGS="$CFLAGS -fstack-protector-all"],[],[]
)

dnl Add hardening linker flags
AX_CHECK_LINK_FLAG([-pie],[LDFLAGS="$LDFLAGS -pie"],[],[])
AX_CHECK_LINK_FLAG([-z relro],[LDFLAGS="$LDFLAGS -z relro"],[],[])
AX_CHECK_LINK_FLAG([-z now],[LDFLAGS="$LDFLAGS -z now"],[],[])

dnl Add glibc hardening
CPPFLAGS="$CPPFLAGS -D_FORTIFY_SOURCE=2"
gibi gibi, ama asıl önemli nokta, ve uygulamanın çalışma prensibiyle alakalı bize en çok ipucu veren bölüm, "libtorsocks.so" olarak isimlendirilmiş bir dosyanın sisteme önyüklemesinin yapılmasıyla ilgili denetimlerin gerçekleştirildiği sektör. Yorum satırında, Linux için ilgili önyüklemenin yapılacağı çevre değişkeninin "LD_PRELOAD", OSX'de ise "DYLD_INSERT_LIBRARIES" olacağına dair bir detay verilmiş.
.\configure.ac
Kod:
TESTLDFLAGS="$LDFLAGS"
AC_SUBST(TESTLDFLAGS)

# libtorsocks için sürüm bilgisi
TORSOCKSLDFLAGS="$LDFLAGS -version-info 1:0:0"

dnl Linker checks for Mac OSX, which uses DYLD_INSERT_LIBRARIES
dnl instead of LD_PRELOAD
case "$host_os" in
darwin*)
    dnl Check if the linker accepts -dynamiclib; necessary on Mac OS X
    AC_MSG_CHECKING(if the linker accepts -dynamiclib)
    OLDLDFLAGS="$TORSOCKSLDFLAGS"
    TORSOCKSLDFLAGS="$TORSOCKSLDFLAGS -dynamiclib"
    AC_TRY_COMPILE(,, [AC_MSG_RESULT(yes)],
		[
			TORSOCKSLDFLAGS="$OLDLDFLAGS"
			AC_MSG_RESULT(no)
		]
	)

    dnl Check if the linker accepts -single_module; necessary on Mac OS X
    AC_MSG_CHECKING(if the linker accepts -single_module)
    OLDLDFLAGS="$TORSOCKSLDFLAGS"
    SHLIB_EXT="so"
    LDPRELOAD="LD_PRELOAD"
    TORSOCKSLDFLAGS="$TORSOCKSLDFLAGS -single_module"
    AC_TRY_COMPILE(,,
		[
			SHLIB_EXT="dylib"
			LDPRELOAD="DYLD_INSERT_LIBRARIES"
			AC_MSG_RESULT(yes)
		],
		[
			TORSOCKSLDFLAGS="$OLDLDFLAGS"
			AC_MSG_RESULT(no)
		]
    )
    ;;
*)
    SHLIB_EXT="so"
    LDPRELOAD="LD_PRELOAD"
    ;;
esac

AC_SUBST(SHLIB_EXT)
AC_SUBST(LDPRELOAD)
AC_SUBST(TORSOCKSLDFLAGS)
İşletim sistemine dair ilgili kontrol, Autoconf aracı bünyesinde tanımlı "$host_os" değişkeninin denetimiyle sağlanıyor. "darwin" olması, yani işletim sisteminin OSX olarak belirlenmesi durumunda barındırılması "zorunlu" olarak tanımlanmış "-dynamiclib" ve "-single_module" linker aracının argümanlarına ekleniyor, "LDPRELOAD" değişkeni "DYLD_INSERT_LIBRARIES" olarak belirleniyor. Aksi bir durumda ise, tekrardan değişken "LD_PRELOAD" olarak ayarlanıyor. Konfigürasyon dosyasının dikkatimi çeken sıkıntılı durumu tam olarak şu oldu, OSX'in içerisinde barındırdığı "LD" aracının "man" sayfası olan ld(1)'e baktığımda, "-single_module" parametresinin artık varsayılan olarak eklendiğini, ek bir biçimde linker aracına argüman olarak tanıtılmasının gerekli olmadığını okudum (ref. https://www.unix.com/man-page/osx/1/ld/). Bu sebepten ötürü, ek olarak linker'a eklenmesi günümüz itibariyle lüzumsuz.

Pekala, nedir bu "LD_PRELOAD" yahut "DYLD_INSERT_LIBRARIES" olarak belirlediğimiz zımbırtılar -bu sorunun cevabını, "torsocks" adlı betik yazılımının "src/bin/Makefile.am" dosyasından yaptığım çıkarımla ulaştığım kaynak kodunu inceledikten sonra vermeyi planlıyorum. "src/bin/torsocks.in" adlı dosyada yer verilen fonksiyonlar, aslında uygulamanın işleyişini tam olarak özetlemekte. İşlevsel fonksiyonları filtreleyerek, uygulamanın akışının gerçekleştirildiği kısma göz atalım.
src/bin/torsocks.in
Kod:
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
LIBDIR="${libdir}/torsocks"
LIB_NAME="libtorsocks"
SHLIB_EXT="@SHLIB_EXT@"
SHLIB="${LIBDIR}/${LIB_NAME}.${SHLIB_EXT}"
[...]
if [ $# -eq 0 ] ; then
	usage
	exit 1
fi

# Ensure libtorsocks exists,
if [ ! -f $SHLIB ]; then
   echo "$0: $SHLIB does not exist! Try re-installing torsocks."
   exit
fi
[...]
Buraya değin uygulama, argüman sayısından yola çıkarak gerekli olması durumunda kullanıcı parametrelerini listeliyor, "${LIBDIR}/${LIB_NAME}.${SHLIB_EXT}" formatında oluşturduğu "SHLIB" adındaki değişkenin içerisinde barındırdığı dosya yolunun barınması durumunda ise uygulama akışına devam ediyor - gayet basit. ".\configure.ac" dosyasından da yola çıkarak elde ettiğimiz verilerimizi, "SHLIB"in formatındaki yere koyduğumuz zaman, "${libdir}/torsocks/libtorsocks.so" adında bir dizin karşımıza çıkıyor. Belli ki işimiz "libtorsocks.so" adındaki dosya ile olacak. Betik akışına devam ettiğimiz zaman,
src/bin/torsocks.in
Kod:
[...]
while true;
do
	case "$1" in
		on)
			check_script_sourced $1
			set_ld_preload
			echo "Tor mode activated. Every command will be torified for this shell."
			break
			;;
		off)
			check_script_sourced $1
			export @ldpRELOAD@=`echo -n  @ldpRELOAD@ | sed "s#$SHLIB *##"`
			if [ -z " @ldpRELOAD@" ]; then
				unset @ldpRELOAD@
				case "$OSTYPE" in
					darwin*)
						unset DYLD_FORCE_FLAT_NAMESPACE
						;;
				esac
			fi
			echo "Tor mode deactivated. Command will NOT go through Tor anymore."
			break
			;;
		show|sh)
			echo  @ldpRELOAD@=" @ldpRELOAD@""
			break
			;;
		-h|--help)
			usage
			break
			;;
		-u|--user)
			if [ -z $2 ]; then
				echo "Missing username to -u" >&2
				exit 1
			fi
			export TORSOCKS_USERNAME=$2
			shift
			;;
		-p|--pass)
			if [ -z $2 ]; then
				echo "Missing password to -p" >&2
				exit 1
			fi
			export TORSOCKS_PASSWORD=$2
			shift
			;;
		-a|--address)
			if [ -z $2 ]; then
				echo "Missing address to -a" >&2
				exit 1
			fi
			export TORSOCKS_TOR_ADDRESS=$2
			shift
			;;
		-P|--port)
			if [ -z $2 ]; then
				echo "Missing port to -P" >&2
				exit 1
			fi
			export TORSOCKS_TOR_PORT=$2
			shift
			;;
		-i|--isolate)
			export TORSOCKS_ISOLATE_PID=1
			;;
		-d|--debug)
			# Set full DEBUG with 5 being the highest possible level.
			export TORSOCKS_LOG_LEVEL=5
			;;
		--shell)
			tor_shell
			break
			;;
		--version)
			echo "Torsocks @version@"
			break
			;;
		*)
			torify_app "$@"
			break
			;;
	esac
	shift
done
satırları karşımıza çıkıyor, dosyaya atanan argümanlar burada denetleniyor ve argümana göre yapılası işlemler belirleniyor. Çevre değişkenleri ile oynamalar yapan satırları filtre edersek, yeni görünüm tam olarak bu oluyor,
Kod:
[...]
while true;
do
	case "$1" in
		on)
			check_script_sourced $1
			set_ld_preload
			echo "Tor mode activated. Every command will be torified for this shell."
			break
			;;
		off)
			check_script_sourced $1
			export @ldpRELOAD@=`echo -n  @ldpRELOAD@ | sed "s#$SHLIB *##"`
			if [ -z " @ldpRELOAD@" ]; then
				unset @ldpRELOAD@
				case "$OSTYPE" in
					darwin*)
						unset DYLD_FORCE_FLAT_NAMESPACE
						;;
				esac
			fi
			echo "Tor mode deactivated. Command will NOT go through Tor anymore."
			break
			;;
		show|sh)
			echo  @ldpRELOAD@=" @ldpRELOAD@""
			break
			;;
		--shell)
			tor_shell
			break
			;;
		*)
			torify_app "$@"
			break
			;;
	esac
	shift
done
Analizini gerçekleştirmemiz gereken fonksiyonlar, argümanın "--shell" olması durumunda çağrılan "tor_shell ()" ile herhangi bir başka değere sahip olmasıyla çağrılan ve takip eden tüm parametrelerin iletildiği "torify_app ()" olacaktır. Şu durumda, betiğin "$torsocks [app, [arg1, arg2, ...]]" biçiminde çalıştırılmasıyla çağrılan fonksiyon "torify_app"ten başkası değildir.
Kod:
torify_app ()
{
	[...]
	#Bu satırın kaldırılması durumunda, uygulama işlevselliğini yitirecektir.
	set_ld_preload
	[...]
	exec "$@"
}
En işlevsel haliyle fonksiyon, şekildeki gibidir. Önce "set_ld_preload" fonksiyonu, sonra ise argüman olarak atanan yazılım ve parametreleri sırasıyla çağrılır. Spoiler veriyorum, "--shell" parametresiyle çağrılan "tor_shell"de de karşılaşacağımız aman aman farklı bir manzara olmayacaktır.
Kod:
tor_shell ()
{
	set_ld_preload
	echo "$0: New torified shell coming right up..."
	${SHELL:-/bin/sh}
}
Dediğim gibi, her iki kemik fonksiyon da temelde "set_ld_preload"ın çağrılması ve takiben herhangi bir yazılımın bağımlı/bağımsız argümanlarca çalıştırılmasıyla işlevsellik kazanmakta. O halde betiğimizde tüm fonksiyonel işlemleri yerine getiren ana fonksiyon, "set_ld_preload ()" imiş.
Kod:
set_ld_preload ()
{
	if [ -z " @ldpRELOAD@" ]; then
		export @ldpRELOAD@="${SHLIB}"
	else
		echo  @ldpRELOAD@ | grep -q "${SHLIB}" || \
			export @ldpRELOAD@="${SHLIB}  @ldpRELOAD@"
	fi

	# OS X'e özgü çevre değişkeni
	case "$OSTYPE" in
		darwin*)
			export DYLD_FORCE_FLAT_NAMESPACE=1
			;;
	esac
}
Türkçesi; eğer ki "-z " @ldpRELOAD@"" denetimimde "LD_PRELOAD" olarak belirlediğim çevre değişkenim tanımlı değil ise, direkt olarak üstüne yaz; aksi halde ilgili değişkenden "${libdir}/torsocks/libtorsocks.so" kısmını kırpıp beni de ekleyerek aynen sakla, maksat teksir önlensin. Tüm betik, paylaşımlı nesnenin "LD_PRELOAD" çevre değişkenine ilavesini gerçekleştirmek maksatlı kullanılıyor. Gelelim "LD_PRELOAD" değişkeninin ne olduğuna, ve GLIBC bünyesinde nasıl bir tanımlamaya sahip olduğuna. Uzun lafın kısası, yazılımlar birtakım fonksiyonlara erişme maksatlı kütüphaneler kullanırlar. İlgili kütüphaneler, derleme yahut çalışma esnasında yüklenebilirler. Çalışma esnasında yüklemenin gerçekleşmesi durumunda, "dynamic linking" olarak nitelendirilen bir olayla karşılaşırız. Bu olayın manipülasyonu gerçekleştirildiği vakit, hali hazırda barınan kütüphanelerin içerisindeki fonksiyonel çağrıların üstüne yazılması yahut tümden değiştirilmesi, yamalanması mümkün kılınır. "LD_PRELOAD" işte tam olarak bundan sorumludur.

"LD_PRELOAD" çevre değişkeni içerisinde, yürütülebilir dosyanın bağımlılıkları işleme alınmadan evvel yüklenecek olan, boşluk veya kolonlarla ayrılmış kütüphaneleri saklar. Herhangi bir executable dosyayı çalıştırdığınız vakit, işletim sistemi içerisinde başlıca ilgili sistem çağrıları süregelir,
Kod:
$(cat <<EOF
> int main (){
> return 0;
> }
> EOF
subsh> ) | gcc -o damn.o -xc -
Kod:
$strace ./damn.o
execve("./damn.o", ["./damn.o"], [/* 83 vars */]) = 0
brk(NULL)                               = 0x8efb000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb77b5000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=157209, ...}) = 0
mmap2(NULL, 157209, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb778e000
close(3)
[...]
exit_group(0)                           = ?
+++ exited with 0 +++
Burada önemli olan nokta, "access("/etc/ld.so.preload", R_OK)" satırında barınan ve access (2) sistem çağrısına (ref. access(2) - Linux manual page) argüman olarak atanmış dizin. Aslında önyükleme olayında kullanılabilecek nesneler, "/etc/ld.so.preload" fiziksel dosyası ve "LD_PRELOAD" çevre değişkeni olmak üzere iki biçimde tanımlanabilir; ki aralarındaki fark zaten güvenlik sebeplerinden ötürü doğan kısıtlamalardır. Normal şartlarda, "/etc/ld.so.preload" yolunda bir dosya bulunmaz; zaten sistem çağrımız bu sebepten ötürü "-1, ENOENT" cevabını döndürdü. Barındırılması, tıpkı "LD_PRELOAD" gibi kullanıcı opsiyonuna bırakılmıştır, ancak ona kıyasla daha ayrıcalıklıdır. Bu noktada, "ld.so" dosyası dikkatimi çeker, dosyanın kaynak kodu GLIBC bünyesindeki "elf/rtld.c" yükleyici dosyasından okunabilir. "LD_PRELOAD" çevre değişkeninde tanımlı nesneler, aşağıdaki fonksiyon aracılığıyla ayrıştırılmaktadır.
elf/rtld.c
Kod:
unsigned int
handle_ld_preload (const char *preloadlist, struct link_map *main_map)
{
  unsigned int npreloads = 0;
  [...]

  while (*p != '\0')
    {
		size_t len = strcspn (p, " :");
		if (len > 0 && len < sizeof (fname))
		{
			memcpy (fname, p, len);
			fname[len] = '\0';
		}
		else
			fname[0] = '\0';

		p += len;
		if (*p != '\0')
			++p;

		if (dso_name_valid_for_suid (fname))
			npreloads += do_preload (fname, main_map, "LD_PRELOAD");
    }
  return npreloads;
}
Fonksiyonda, kolon ve boşluk karakterlerinden string ifade ayrıştırılıyor, sonrasında ise ayrıştırılan değer "dso_name_valid_for_suid ([...])" adında bir fonksiyona argüman olarak atanıyor; aslında "LD_PRELOAD" ile "/etc/ld.so.preload" dosyası arasındaki temel fark tam olarak bu, yama esnasında birtakım fonksiyonların yahut dosya yolu gibi değerlerin denetlenmesi gerçekleştiriliyor.
elf/rtld.c
Kod:
static bool
dso_name_valid_for_suid (const char *p)
{
  if (__glibc_unlikely (__libc_enable_secure))
    {
      size_t len = strlen (p);
      if (len >= SECURE_NAME_LIMIT || memchr (p, '/', len) != NULL)
	return false;
    }
  return *p != '\0';
}
Ve de "__libc_enable_secure" değerini belirleyen kod parçacıklarından birisi ise, "elf/enbl-secure.c" dosyasında tanımlanmış. Sonuç itibariyle, herhangi bir "setuid ([...])" yazılımının yahut birtakım ayrıcalıklara sahip uygulamaların "LD_PRELOAD" aracılığıyla manipülasyonu güvenlik sebepleri nedeniyle kısıtlanmış durumdadır. Kodu daha rahat okuyabilmeniz için, ek olarak "usr/include/sys/cdefs.h" içerisinde tanımlı "__glibc_unlikely (...)" makrosunu da bırakıyorum.
elf/enbl-secure.c
Kod:
vo id
__libc_init_secure (vo id)
{
  if (__libc_enable_secure_decided == 0)
    __libc_enable_secure = (__geteuid () != __getuid ()
			    || __getegid () != __getgid ());
}
;usr/include/sys/cdefs.h #define __glibc_unlikely(cond) __builtin_expect((cond), 0)
Her ne ise, denetleme sonrasında ise, "do_preload ([...])" çağrılıyor ve önyükleme işlemi burada son buluyor. Her türlü bağımlılıklardan evvel, sizin belirlediğiniz paylaşımlı nesneler uygulama bünyesine katılıyor. Bunu basit bir örnekle test edip, örneklendirip sonrasında tekrardan "torsocks" üzerinden anlatımımıza devam etmek istiyorum. Örnek üzerinde, GLIBC bünyesindeki "puts ([...])" fonksiyonunun üzerine yazacak, ayrıyeten "rand ([...])" dönütümü sürekli olarak "4"e eşitleyeceğiz.
Kod:
$ (cat <<EOF
> #define _GNU_SOURCE
> #include <dlfcn.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> static int (*glibc_puts)(const char* str) = NULL;
> int puts (const char* str){
> 	printf ("u mate, thus ur strlen, %zu\n", strlen (str));
> 	glibc_puts = dlsym (RTLD_NEXT, "puts");
> glibc_puts (str); return 0;
> 	}
> int rand(){ return 4; }
> EOF
> ) | gcc -Wl,--no-as-needed -ldl -shared -fPIC -o rnd.so -xc -
İlgili paylaşımlı nesne objemiz, oluşturduğumuz dizinde an itibariyle "rnd.so" ismiyle barınmakta. Hedef uygulama ise,
Kod:
$ (cat <<EOF
> #include <stdlib.h>
> #include <time.h>
> #include <stdio.h>
> int main(){
> 	srand(time(NULL));
> 	char str[40];
> 	sprintf (str, "rnd val: %d", rand()%100);
> puts (str);
> 	return 0;
> }
> EOF
> ) | gcc -o damn.o -xc -
kaynak koduyla, "damn.o" ismiyle aynı dizinde barınmakta. An itibariyle yapılması gereken, "LD_PRELOAD" çevre değişkenine paylaşımlı nesnemizi verip uygulamayı çalıştırmaktan ibaret.
Kod:
$LD_PRELOAD=/home/knuth/rnd.so ./damn.o
u mate, thus ur strlen, 10
rnd val: 4

.komikli_gorsel

Rastgele değerimiz, "rand ([...])" fonksiyonunun üstüne yazmamızla rastgelelikten çıkmış, böylece "4"e eşitlenmiş; "puts([...])" fonksiyonu ise aldığı değerin uzunluğunu da ekrana yazdıracak biçimde yama yapılmış vaziyette. Peki az önce ne oldu, tam olarak yazının şu zamanına değin bahsettiklerimiz özetlenmiş hale geldi. "dynamic linking" olayının manipülasyonunu gerçekleştirdik, executable dosyanın bağımlılıklarında yer alan fonksiyonların üstüne yazdık. Her iki durum arasındaki fark, şu biçimde açıkça ortadadır,

Kod:
$ ldd damn.o
        linux-gate.so.1 =>  (0xb7706000)
        libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7526000)
        /lib/ld-linux.so.2 (0xb7707000)
$ LD_PRELOAD=/home/knuth/rnd.so ldd ./damn.o
        linux-gate.so.1 =>  (0xb7792000)
        /home/knuth/rnd.so (0xb778c000)
        libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75af000)
        libdl.so.2 => /lib/i386-linux-gnu/libdl.so.2 (0xb75aa000)
        /lib/ld-linux.so.2 (0xb7793000)
"/home/knuth/rnd.so (0xb778c000)". "LD_PRELOAD" çevre değişkeninin örneklemesini yaptığımıza göre, "torsocks" adlı yazılımın bu değişken vasıtasıyla fonksiyonel davranışlarına tekrardan dönebiliriz. Elbette ki "torsocks" bünyesinde barınan "${libdir}/torsocks/libtorsocks.so" paylaşımlı nesnesi de, tıpkı örneğimizdeki gibi birtakım çağrıların üstüne yazılmış versiyonlarını içermektedir. Bu çağrıların tümü, "src/lib" içerisinde listelenmiştir. İncelememiz gereken ilk temel unsur, her dosyada içe aktarılmış olan "torsocks.h" başlık dosyasıdır. İçerisinde, TSOCKS kütüphanesinin mimarisini özetleyecek biçimde, GLIBC bünyesindeki fonksiyonların isimleri, dönüt veritipleri ile argümanları, sıkça kullanılan birtakım makrolar tanımlanmıştır.
src/lib/torsocks.h
Kod:
#define TSOCKS_LIBC_DECL(name, type, sig) \
	type (*tsocks_libc_##name)(sig);
#define TSOCKS_DECL(name, type, sig) \
	extern type tsocks_##name(sig);
Olarak tanımlanan "TSOCKS_LIBC_DECL" ile "TSOCKS_DECL", torsocks tarafından manipüle edilen her türlü sembol için oluşturulup içerisinde fonksiyon göstericilerini tutar. Temel maksat, LIBC çağrısını "torsocks" dışarısında kullanabilmektir. Bunun haricinde, her bir fonksiyon için dosya içerisinde,
Kod:
#include <[file_that_contains_symbol].h>
#define LIBC_[symbol]_NAME [symbol]
#define LIBC_[symbol]_NAME_STR XSTR(LIBC_[symbol]_NAME)
#define LIBC_[symbol]_RET_TYPE [type]
#define LIBC_[symbol]_SIG [type] [arg1, [arg2,]]
#define LIBC_[symbol]_ARGS [arg1, [arg2,]]
notasyonuyla tutulmaktadır. Böylelikle, dizinde bulunan "*.c" dosyalarındaki geliştirici dostu yapı korunmuştur. Az önce bahsetmiş olduğumuz hali hazırda LIBC fonksiyonlarının saklanması ile, aşağıdaki formatta yine her bir fonksiyon için tekrarlanmıştır,
Kod:
extern TSOCKS_LIBC_DECL([symbol], LIBC_[symbol]_RET_TYPE, LIBC_[symbol]_SIG)
TSOCKS_DECL([symbol], LIBC_[symbol]_RET_TYPE, LIBC_[symbol]_SIG)
#define LIBC_[symbol]_DECL \
	LIBC_[symbol]_RET_TYPE LIBC_[symbol]_NAME(LIBC_[symbol]_SIG)
Sonuç itibariyle elimizde hali hazırda bulunan fonksiyonu tutar iken, ilgili fonksiyonun yerine geçecek olan yamayı da tanımlıyoruz. "src/lib/torsocks.h" üzerinde fonksiyon prototifleri harici oluşturulan yapı genel itibariyle bu idi. Ayrıyeten,
Kod:
enum tsocks_sym_action {
	TSOCKS_SYM_DO_NOTHING		= 0,
	TSOCKS_SYM_EXIT_NOT_FOUND	= 1,
};
src/lib/torsocks.c
Kod:
vo id *tsocks_find_libc_symbol(const char *symbol,
		enum tsocks_sym_action action)
{
	vo id *fct_ptr = NULL;
	assert(symbol);
	fct_ptr = dlsym(RTLD_NEXT, symbol);
	if (!fct_ptr) {
		ERR("Unable to find %s", symbol);
		if (action == TSOCKS_SYM_EXIT_NOT_FOUND) {
			ERR("This is critical for torsocks. Exiting");
			clean_exit(EXIT_FAILURE);
		}
	}

	return fct_ptr;
}
ifadesinde de, ilgili sembolün bulunmaması durumunda gerçekleştirilecek işlem de özetlenmiştir. Misal, "torsocks" için gerekli olan connect (2) sistem çağrısının bulunmaması durumunda, "TSOCKS_SYM_EXIT_NOT_FOUND (=1)" işleminin gerçekleşeceği, yani uygulamadan çıkılacağı belirtiliyor. Dizinde yer alan "*.c" dosyalarının içerisinde ise, artık "torsocks.h" dosya mimarisini anlamamızla beraber okunabilirliği kolaylaşacak bir notasyon hakim.

Kod:
TSOCKS_LIBC_DECL([symbol], LIBC_[symbol]_RET_TYPE, LIBC_[symbol]_SIG)

LIBC_[symbol]_RET_TYPE tsocks_[symbol](LIBC_[symbol]_SIG)
{
	[...]
	libc_call:
		return tsocks_libc_[symbol](LIBC_[symbol]_ARGS);

	error:
		return -1;
}
LIBC_[symbol]_DECL
{
	[...]
	return tsocks_[symbol](LIBC_[symbol]_ARGS);
}
oldukça basit bir yapı. "src/common" dizininde ise uygulama genelinde kullanılmış olan birtakım fonksiyonlar ve makrolar yatmaktadır. İşte, "torsocks" içeriğinde genel olarak bu yapı süregelmektedir. Fonksiyonların biraz daha derinine dalmadan evvel, örnek bir çalıştırma esnasındaki davranışlarını sunmak istiyorum.
Kod:
$strace torsocks curl checkip.amazonaws.com
execve("/usr/bin/torsocks", ["torsocks", "curl", "checkip.amazonaws.com"], [/* 84 vars */]) = 0
[..]
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
[...]
open("/lib/i386-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
[...]
open("/usr/bin/torsocks", O_RDONLY)     = 3
[...]
geteuid32()                             = 0
getegid32()                             = 0
[...]
stat64("/usr/lib/i386-linux-gnu/torsocks/libtorsocks.so", {st_mode=S_IFREG|0644, st_size=79220, ...}) = 0
pipe([3, 4])                            = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb7566768) = 6463
close(4)                                = 0
read(3, "/usr/bin/curl\n", 128)         = 14
read(3, "", 128)
Tam olarak beklenilen davranışları sergiliyor, "/usr/lib/i386-linux-gnu/torsocks/libtorsocks.so" ismindeki paylaşımlı nesneyi içe aktarıyor. "libtorsocks.so" dosyasının içerisinde barındırılan sembolleri de listelersek,
Kod:
$rabin2 -sr /usr/lib/i386-linux-gnu/torsocks/libtorsocks.so -l | grep -v "^f sym.imp"
fs symbols
f sym.tsocks_initialize 72 0x00001ee0
f sym.connect 108 0x00003250
f sym.tsocks_tor_resolve 812 0x00002810
Cd 4 @ 0x0001434c
f sym.tsocks_libc_gethostbyname2 4 0x0001434c
f sym.tsocks_gethostbyaddr_r 533 0x000037a0
f sym.gethostbyaddr_r 148 0x000039c0
f sym.tsocks_getaddrinfo 503 0x00003e60
f sym.tsocks_close 241 0x000040f0
f sym.tsocks_sendto 239 0x00005940
f sym.listen 122 0x00005710
[...]
f sym.tsocks_fclose 311 0x00005790
f sym.socketpair 142 0x00004bd0
f sym.tsocks_gethostbyname2 92 0x00003490
Cd 4 @ 0x00014340
f sym.tsocks_libc_gethostbyname 4 0x00014340
Cd 255 @ 0x00014380
f sym.tsocks_he_name 255 0x00014380
f sym.tsocks_listen 365 0x000055a0
f sym.tsocks_tor_resolve_ptr 592 0x00002b40
Cd 20 @ 0x00014480
f sym.tsocks_he 20 0x00014480
Cd 4 @ 0x00014498
[...]
f sym.tsocks_libc_connect 4 0x0001433c
Cd 4 @ 0x000144a4
f sym.tsocks_libc_socket 4 0x000144a4
f sym.tsocks_mutex_lock 131 0x00007980
Cd 8 @ 0x00014364
f sym.tsocks_he_addr_list 8 0x00014364
f sym.getaddrinfo 142 0x00004060
f sym.tsocks_accept4 373 0x00005390
f sym.__bss_start 0 0x00014078
f sym.tsocks_mutex_destroy 99 0x00007910
Cd 4 @ 0x000144b8
f sym.tsocks_libc_accept4 4 0x000144b8
f sym.syscall 122 0x00004a60
Cd 16 @ 0x00000000
CCa entry0 libdl.so.2
CCa entry0 libc.so.6
misali geniş bir manzarayla karşılacağız. Beklenilen gibi, "tsocks_libc_##name" formatında GLIBC fonksiyonlarının göstericileri, "tsocks_##name" notasyonunda ise yama saklanmakta. Kaynak kodlarındaki kaybolmuş vaziyetimizi sonlandırmayı, küçük bir sistem çağrısı örneğiyle istiyorum. En temel haliyle, Assembly (nasm sözdizimi) dilinde bir ağ yazılımı aşağıdaki gibi bir yapıya sahiptir, temel sistem çağrılarını kullanır,
Kod:
BITS 32
; sock = socket(2, 1, 0)
push BYTE 0x66
pop eax
cdq
xor ebx, ebx
inc ebx
push edx
push BYTE 0x1
push BYTE 0x2
mov ecx, esp
int 0x80
mov esi, eax

; bind(sock, [2, 8000, 0], 16)
push BYTE 0x66
pop eax
inc ebx
push edx 
push WORD 0x401f ; PORT = 8000
push WORD bx
mov ecx, es
push BYTE 16
push ecx
push esi
mov ecx
int 0x80

; listen(sock, 0)
mov BYTE al, 0x66
inc ebx
inc ebx 
push ebx
push esi
mov ecx, esp
int 0x80

; cli = accept(sock, 0, 0)
mov BYTE al, 0x66
inc ebx
push edx
push edx
push esi
mov ecx, esp
int 0x80
Şu durumda uygulamanın işlevi yalnızca "8000(=0x1f40)" ağ portunu dinlemekten ibaret. Kullanılan sistem çağrıları sırasıyla "socket, bind, listen ve accept". İlgili çağrıların tamamı doğal olarak dizin içerisinde mevcuttur. Gönül isterdi ki biraz daha derine inip, ilgili fonksiyonların implementasyonlarına değineyim; ancak konunun fazla uzadığının farkına vararak, bunu diğer konularıma bırakıyorum. Dilerseniz bahsettiğim kaynak kodlarını inceleyebilirsiniz (ref. https://github.com/dgoulet/torsocks/). Aslen tüm bu yaygaranın tek sebebi, "src/common" içerisinde barındırılan methodların ana fonksiyon içerisinde çağrılmasından kaynaklı.
Kod:
vo id __attribute__((constructor)) tsocks_initialize(vo id)
{
	tsocks_once(&init_once, &tsocks_init);
}
Kod:
static vo id tsocks_init(vo id)
{
	int ret;
	is_suid = (getuid() != geteuid());

	init_logging();
	init_libc_symbols();
	init_config();

	[...]
}
"tsocks" kütüphanesinin kullandığı konfigürasyon dosyasının işlenmesi ise, "DEFAULT_CONF_FILE_ENV" çevre değişkeninde tutulan dosya yolunda barınan dosyanın içeriğinin nesneye aktarılmasıyla gerçekleşmekte. Anlayacağınız, varsayılan bilgileri bu konfigürasyon dosyası aracılığıyla kendi platformunuza uyarlayabilirsiniz. Hem çevre değişkenlerinde tutulan, hem de konfigürasyon dosyasında barındırılan veriler, uygulama akışında kullanılmakta -tabii çevre değişkenleri öncelikli.
src/lib/torsocks.c
Kod:
static vo id read_env(vo id)
{
	int ret;
	const char *username, *password, *allow_in, *isolate_pid, *tor_address, *tor_port;

	if (is_suid) {
		goto end;
	}

	allow_in = getenv(DEFAULT_ALLOW_INBOUND_ENV);
	if (allow_in) {
		ret = conf_file_set_allow_inbound(allow_in, &tsocks_config);
		if (ret < 0) {
			goto error;
		}
	}

	[...]

end:
	return;
error:
	clean_exit(EXIT_FAILURE);
}
Kod:
static vo id init_config(vo id)
{
	int ret;
	const char *filename = NULL;

	if (!is_suid) {
		filename = getenv(DEFAULT_CONF_FILE_ENV);
	}

	ret  = config_file_read(filename, &tsocks_config);
	[...]
	if (tsocks_config.conf_file.tor_port == 0) {
		tsocks_config.conf_file.tor_port = DEFAULT_TOR_PORT;
	}
	[...]
	read_env();

	[...]
}
Evet, artık noktayı koymak istiyorum.

.son
"torsocks" isimli yazılımın arka planda gerçekleştirdiklerine, bağımlılıklarına adım adım tanık olduk. Ulaştığımız tüm bilgiler, herhangi bir başka açık kaynak kodlu yazılımda da olabileceği gibi tamamıyla yazılımın dokümanlarından ve kaynak kodunu yorumlamamızdan derlemedir. "torsocks" temelde bir betik yazılımı olup, "LD_PRELOAD" çevre değişkeni aracılığıyla henüz hiçbir bağımlılık uygulamaya aktarılmamışken yüklenen ve "tsocks" olarak isimlendirilen kütüphanenin (ELF paylaşımlı nesnesi) kolay bir biçimde kullanımını sağlar. Kütüphane ise uygulama içerisindeki ağ methodlarının üstüne yazılmasından, yamalanmasından sorumludur. Haliyle, platforma özgü davranışları neticesinde aynı method ile "Windows" işletim sisteminde çalıştırılabilmesi mümkün değildir. Elbette, paylaşımlı nesnenin cihazda yer alması durumunda betiğe gerek kalmaksızın da kullanılabilir şu biçimde,
Kod:
$ LD_PRELOAD=/path/to/libtorsocks.so <app [arg1, arg2,]>
Yeterince olmasa da, anlaşılabilir bir biçimde X-Ray görüşü üzerinden uygulamayı analiz ettiğimizi düşünüyorum. Sonuç itibariyle anlıyoruz ki, ilgili yazılım arka planında fiziksel yasalara karşı gelen gizemli bir geçmiş barındırmıyor imiş. Yazıyı okuduğunuz için teşekkürlerimi sunuyorum. Siber güvenlik ekibi, şimdilik sundu.

.knuth
    


___________________________________________


Kod:
__asm__ (
    ".att_syntax noprefix\n\t"
    //"pushl %ebp\n\t"
    //"movl %esp, %ebp\n\t"
    "movl $0, %eax\n\t"
    "movb $0, 0(%eax)\n\t"
    "popl %ebp\n\t"
    "retl\n\t"
); /* *(PBYTE)0 = 0; */
 Offline  
 
Alıntı ile Cevapla
Alt bir Hafta önce   #2
  • Binbaşı
  • Üye Bilgileri
Üyelik tarihi
10/2015
Nereden
SpaceX
Mesajlar
Konular


  


Hocam kalite kokuyor. Mükemmel bir konu. Sağolun
    


___________________________________________


Troubled İlayda from Adıyaman
 Offline  
 
Alıntı ile Cevapla
Alt bir Hafta önce   #3
  • Albay
  • Üye Bilgileri
Üyelik tarihi
08/2017
Nereden
Makedonya
Mesajlar
Konular


  


Ellerinize sağlık, şüphesiz muazzam ve detaylı bir anlatım olmuş
    


___________________________________________

ςђ43 ω нєгє

 Offline  
 
Alıntı ile Cevapla
Alt bir Hafta önce   #4
  • AR-GE Tim (Bug.Res.)
  • Üye Bilgileri
Üyelik tarihi
09/2016
Mesajlar
Konular


  


Elinize sağlık
    


___________________________________________

"Whether I win or lose is up to me."
 Offline  
 
Alıntı ile Cevapla
Alt bir Hafta önce   #5
  • Moderasyon Sorumlusu
  • Üye Bilgileri
Üyelik tarihi
04/2013
Mesajlar
Konular


  


Eline sağlık
    


___________________________________________

Turkhackteam dışında sosyal medya,forum ve gruplarda hesabım bulunmamaktadır .

 Offline  
 
Alıntı ile Cevapla
Alt bir Hafta önce   #6
  • Binbaşı
  • Üye Bilgileri
Üyelik tarihi
08/2017
Nereden
Russia
Yaş
18
Mesajlar
Konular


  


Ellerinize Sağlık
    


___________________________________________

Kelimeler Albayım;bazı anlamlara gelmiyor.
 Offline  
 
Alıntı ile Cevapla
Alt bir Hafta önce   #7
  • Forumdan Uzaklaştırıldı
  • Üye Bilgileri
Üyelik tarihi
12/2007
Mesajlar
4
Konular
2


  


emeğinize sağlık
    
 Offline  
 
Alıntı ile Cevapla
Alt bir Hafta önce   #8
  • Yüzbaşı
  • Üye Bilgileri
Üyelik tarihi
12/2015
Mesajlar
Konular


  


Elinize sağlık
    


___________________________________________

Yeni Bir Başlangıç

OLMADİ ...
 Offline  
 
Alıntı ile Cevapla
Alt 4 Gün önce   #9
  • Üsteğmen
  • Üye Bilgileri
Üyelik tarihi
03/2017
Mesajlar
Konular


  


Elinize sağlık. İlgi görmemesi acayip.
    


___________________________________________

qRunt'x'
 Online  
 
Alıntı ile Cevapla
Alt 4 Gün önce   #10
  • Yüzbaşı
  • Üye Bilgileri
Üyelik tarihi
01/2018
Nereden
Video Editör
Mesajlar
Konular


  


Elinize Sağlık
    


___________________________________________

Unutma Türk. “Korkma” diye başlıyor senin İstiklal Marşın!
 Offline  
 
Alıntı ile Cevapla
Cevapla

Bookmarks

Seçenekler


Bilgilendirme Turkhackteam.net/org
Sitemizde yer alan konular üyelerimiz tarafından paylaşılmaktadır.
Bu konular yasalara uygunluk ve telif hakkı konusunda yönetimimiz tarafından kontrol edilse de, gözden kaçabilen içerikler yer alabilmektedir.
Bu tür konuları turkhackteamiletisim [at] gmail.com mail adresimize bildirebilirsiniz, konular hakkında en kısa sürede gerekli işlemler yapılacaktır.
Please Report Abuse, DMCA, Harassment, Scamming, Warez, Crack, Divx, Mp3 or any Illegal Activity to turkhackteamiletisim [at] gmail.com

Türkhackteam saldırı timleri Türk sitelerine hiçbir zararlı faaliyette bulunmaz.
Türkhackteam üyelerinin yaptığı bireysel hack faaliyetlerinden Türkhackteam sorumlu değildir. Sitelerinize Türkhackteam ismi kullanılarak hack faaliyetinde bulunulursa, site-sunucu erişim loglarından bu faaliyeti gerçekleştiren ip adresini tespit edip diğer kanıtlarla birlikte savcılığa suç duyurusunda bulununuz.



         

Powered by vBulletin® Copyright ©2000 - 2018

TSK Mehmetçik Vakfı

Türk Polis Teşkilatını Güçlendirme Vakfı



Google+

wau

Search Engine Friendly URLs by vBSEO 3.6.0 ©2011, Crawlability, Inc.