17.04.2024

PSReadline ve komut geçmişinde aramalar yapmak

Linux'ta (bash veya zsh) Ctrl+R aracılığıyla geçmişte arama yapmak mümkün. Powershell'de de benzer bir işlev var. Ctrl+R'ye bastığımda yazdığım anahtar kelime ile geçmişte geriye doğru bir arama yapabiliyorum. İlk çıkan sonuçtan sonra aramayı devam ettirerek bir öncekine ulaşmak için Ctrl+R'ye basmaya devam edebiliyorum. Ctrl+S ise aramanın yönünü değiştirerek ileriye doğru aramaya geçiyor. Arama geçmiş komutların içinde geçen herhangi bir parçaya göre yapılıyor.

Benzer bir işlev de F8 ile mümkün. Bu ise aramayı sadece yazdığım anahtar kelime ile başlayanlar ile kısıtlıyor. F8'e basmaya devam ederek geçmişte bir adım geriye gidebiliyor veya Shift+F8 ile arama yönünü çevirerek ileriye doğru gidebiliyorum.

Bu işlevleri bana sunan PSReadLine'ın kısayol tuşlarının listesini aşağıdaki komutla almak mümkün [1]:

Get-PSReadlineKeyHandler | ? {$_.function -like '*hist*'}

PSReadLine'ın bütün klavye kısayolları atamalarını görmek için

Get-PSReadLineKeyHandler

ve henüz atanmamış işlevleri görmek için ise

Get-PSReadLineKeyHandler -Unbound

kullanabiliriz. Yeni bir işlev ataması yapmak da mümkün. Örneğin henüz bir klavye ataması yapmadığım CaptureScreen işlevini Ctrl+Alt+p klavye kısayoluna atamak için

Set-PSReadLineKeyHandler -Chord 'Ctrl+Alt+p' -Function CaptureScreen

 yapabiliriz. Herhangi bir klavye kısayolunun bir atamada kullanılıp kullanılmadığını sorgulamak için Shift+Alt+* (İngilizce kaynaklarda Alt+? denmiş ama Türkçe klavyelerde bu sıfır (0)'ın yanındaki asteriks (*)'e Shift ve Alt ile basmak demek) bastıktan sonra istenen klavye kısayoluna basmak yeterli. Klavyelerin sağ bölümünde bulunan keypad'deki tuşlar gibi sıradışı tuşların isimlerini öğrenmek için ise aşağıdaki komutu yazdıktan sonra istenen tuşa basmak yeterli:

[System.Console]::ReadKey()

 ---

[1] https://serverfault.com/questions/891265/how-to-search-powershell-command-history-from-previous-sessions

[2] https://learn.microsoft.com/en-us/powershell/scripting/learn/shell/using-keyhandlers?view=powershell-7.4

15.04.2024

Windows'da betikleri bekletmek

Powershell'in Start-Sleep cmdlet'i betiklerde gerekli süre boyunca beklemek için ideal.

Start-Sleep -Seconds 5

Peki bunu komut satırındaki bat dosyalarında nasıl yaparız? Eskiden sleep gibi bir komut vardı, Windows'da, ama artık yok.

İlk yöntem belki de bat dosyasının içinden powershell komutu çalıştırmak olabilir.

powershell "start-sleep -seconds 5"

Bazı yaratıcı beyinler 5 kere ping atmanın ve çıkışı nul'a göndermenin işe yarayacağını söylemiş:

ping 1.1.1.1 -c 5 > nul

Güzel. Daha güzeli timeout:

timeout 5

Bir tuşa basana kadar beklemesi için pause olabilir:

pause
Press any key to continue...

Bunun eşdeğeri powershell'de Read-Host olabilir

Read-Host "Bir tuşa basın..."

Ayrıca [1] ve [2]'de choice ve waitfor komutlarından da bahsedilmiş:

waitfor /t 5 pause
choice /c AB /N /T 5 /D A /M "5 sn bekliyorum"

---

[1] https://www.wikihow.com/Delay-a-Batch-File

[2] https://stackoverflow.com/questions/1672338/how-to-sleep-for-five-seconds-in-a-batch-file-cmd

14.04.2024

Batch dosyalarında değişkenler

Powershell'de tarih ve saati bir değişkene atmak basit:

$tarih_saat = Get-Date -Format "yyyy-MM-dd HH:mm:ss"

Ancak bunun eşdeğeri batch dosyalarında bu şekilde olmuyor. Ben şöyle bir yol buldum:

echo @off
for /f "tokens=*" %%a in ('date /t') do set tarih=%%a
for /f "tokens=*" %%b in ('time /t') do set saat=%%b
set tarih_saat=%tarih%- %saat%

6.04.2024

openssh ile ilgili xz-utils arka kapısı hakkında (CVE-2024-3094)

Hikaye uzun. Uzun lafın kısası, bir Microsoft yazılımcısı, Andres Freund, OSS-Security'ye bulduğu arka kapı ile ilgili bir eposta gönderiyor ve olay patlıyor.

Benim için önemli olan etkilenen sistemler nasıl tespit edilmeli, hangi sürümlerden korunmalı.

xz-utils paketinin sürümlerine bakmak gerek.

xz --version

ile sürüm kontrolü yapılabilir. 5.6.0 ve 5.6.1 sürümleri kaçınılması gereken sürümler. Ayrıca Debian türevlerinde:

apt list installd xz-utils

Fedora türevlerinde

rpm -q xz

ile sürüm numaraları bulunup yükseltilebilir.

Çevremdeki kurulumlardan birinde 5.6.1'e rastladım:

xz --version ile görüntülenen sürüm numarası 5.6.1 olmasına rağmen asıl sürüm numaram 5.6.1-2, ki bu da arka kapıya karşı yamalanış sürüm. Sonraki satırda pacman -Q xz ile bunu doğruladım. Benim xz güncellemelerim nasıl olmuş diye bakmak istedim:

grep "xz " /var/log/pacman.log

çıktı şöyle oldu:

[2024-03-09T23:57:14+0300] [ALPM] upgraded lib32-xz (5.4.6-1 -> 5.6.0-1)
[2024-03-31T01:08:10+0300] [ALPM] upgraded xz (5.6.0-1 -> 5.6.1-2)
[2024-03-31T01:08:13+0300] [ALPM] upgraded lib32-xz (5.6.0-1 -> 5.6.1-2)

Demek ki Manjaro, 31 Mart'ta yamayı yayınlamış. Debian ve Fedora ana dağıtımlar sorunlu paketleri depolarına dahil etmediği için hala güvenli olarak görüldüler. Ancak "bleeding edge" olarak nitelenen "rolling distro"lar için çok olumlu nitelendirmeler kullanılmadı. Rolling distro deyince de ilk akla gelen Arch Linux. Ama şu sayfada denmiş ki; Arch Linux xz paketini openssh ile ilişkilendirmediği için Arch Linux bu saldırıdan etkilenmemiş.

Eğer sistemdeki sürümü eski sürüme downgrade etmek isteseydim /var/cache/pacman/pkg altındaki paket önbelleğindeki sürümleri kullanabilirdim:

sudo pacman -U /var/cache/pacman/pkg/xz-5.4.4-1-x86_64.pkg.tar.zst

Bundan sonra bu paketin kontrolsüz olarak güncellenmesini engellemek için ise /etc/pacman.conf dosyasına şu satırı eklemem gerekecekti:

IgnorePkg = xz

Alternatif olarak manjaro-downgrade paketi ile bu işin otomatize edilmesi de anlatılmış, ama sisteme bir paket daha kurmak istemedi canım, nedense.

---
https://www.openwall.com/lists/oss-security/2024/03/29/4

https://archlinux.org/news/the-xz-package-has-been-backdoored/

https://wiki.manjaro.org/index.php?title=Downgrading_packages 

https://snyk.io/blog/the-xz-backdoor-cve-2024-3094/

https://www.logpoint.com/en/blog/emerging-threats/xz-utils-backdoor/#
https://www.reddit.com/r/linux/comments/1bqt999/backdoor_in_upstream_xzliblzma_leading_to_ssh/
https://www.youtube.com/watch?v=0pT-dWpmwhA

https://forum.manjaro.org/t/xz-package-contains-a-vulnerability/159028/20

https://boehs.org/node/everything-i-know-about-the-xz-backdoor

https://www.wired.com/story/jia-tan-xz-backdoor/

5.04.2024

Windows Time

Zaman eşitlemesi önemli bir iş. Windows sunucularda da bu amaçla çalışan bir hizmet var; "Windows Time".

PS> gsv w32Time
Status Name DisplayName
------ ---- -----------
Running w32time Windows Time

NTP protokolü de, bilindiği gibi, UDP 123 üzerinden çalışıyor. Bu portun açık olması, arka planda bir zaman sunucusunun etkin olduğunu düşünebilmek için ilk koşul.

ncat -z -v -u 192.168.1.1 123

Yerel ağımızda çalışan bir Windows sunucuyu, linux makinalar tarafından güvenilir bir zaman sunucusu olarak kullanabilir, veya tam tersi linux sunucuyu da Windows makinalar tarafından güvenilir bir zaman sunucusu (NTP) ayarlayabiliriz; teknik olarak mümkün.

Bu hizmetin çalışmasını komut satırından yapabilmek için w32tm komutu var. Örnek olarak bizim bilgisayarımızın saati senkronize edeceği kaynak NTP sunucusu olarak hangi adresi kullandığını bulmak için

w32tm /query /source

kullanabiliriz. Windows Time hizmeti ve zaman eşitleme durumu ile ilgili ayrıntılı bilgi için ise

w32tm /query /status

kullanılabilir. Yerel bilgisayarda NTP sunucumuzu bulmak için regisry kullanmak istersek okumamız gereken alan HKLM:\SYSTEM\CurrentControlSet\Services\W32Time\Parameters altındaki NtpServer değeri:

(gp -Path HKLM:\SYSTEM\CurrentControlSet\Services\W32Time\Parameters -Name NtpServer).NtpServer

Bu değeri komut satırından değiştirmek ve uygulamaya geçirmek için aşağıdaki komutlar gerekli:

gsv w32time | spsv
w32tm /config /syncfromflags:manual /manualpeerlist:"192.168.1.1 192.168.1.2"
gsv w32time | sasv
w32tm /config /update
w32tm /resync /rediscover

Bundan sonra herhangi bir anda zaman kaynak sunucumuzdan zaman eşitlemesi yapmak için

w32tm /resync

yeterli.

---

https://learn.microsoft.com/en-us/windows-server/networking/windows-time-service/windows-time-service-tools-and-settings?tabs=config
https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/ff799054(v=ws.11)

4.04.2024

Windows API'lerinde ~256 karakterlik tam yol adı sınırlaması

Kullanıcıların dosyalarına neden uzun uzun isimler vermeyi tercih etmeleri üzerine yazılan tezleri araştırmadan önce böyle bir yol izlemiş kişilerin dosyalarını kopyalarken karşılaşılan hataların çözümüne kafa yordum. Microsoft'un niye böyle bir kısıtlamaya ihtiyacı var diye düşündüm. Sonra öğrendim ki Windows 10 1607 sürüm ve üstünde bu kısıtlamayı kaldırmayı seçebiliyormuşuz [1]. Bilmeden bu kısıtlamaya takıldığım için üzüldüm.

İkinin sekizinci kuvveti olması sebebiyle 256 olarak hafızalarda yer etmesine rağmen aslında 260 karakterlik bir sınır söz konusu. Çünkü sürücü adı, iki nokta üst üste, bir ters bölü ve en sondaki NUL karakterini de sayarsak aslında 256 karakterlik klasör  ve dosya isimlerinin toplamına 4 daha ilave ederek 260'a ulaşıyoruz.

Yerel bilgisayarda çalışırken mutlu mesut +260 karakterlik isimler ile klasör oluşturup dosya kaydedebilen, bunları tekrar açabilen kullanıcı, aslında bu dosyaları kopyalayamıyor, yeniden adlandıramıyor hatta silemiyor (ortalama bir kullanıcının robocopy kullanmadığını varsayarak [3]). Ta ki bir gün bu verilerin başka bir diske veya başka bir bilgisayara kopyalanması gerekene kadar. Bunu da yaparken ya eksik kopyalanıyor, ya da bir bilenden yardım isteniyor. Kopyalama sırasında Windows kullanıcıya çok yardımcı olmadığı için o anda ekranda görüntülenen mesajda tam olarak hangi dosya veya klasörün 260 sınırından daha fazla isme sahip olduğunu göremiyor. Bu durumda görüntülenen hata mesajında "Atla" tuşuna basıp işlem bittikten sonra aslında işlemin bitmediğini, eksik kalan dosyaları aramak zorunda olduğumuz ikinci aşamaya geçtiğimizi farkediyoruz. Böyle bir durumda hangi dosyaların kopyalanmadığını bulabilmek için Powershell ile aşağıdaki gibi bir komut ile dosyalar tespit edilerek bir dosyaya yazılabilir [2].

dir -recurse | where {$_.Fullname.Length -gt 260} | select Name | out-file uzun-dosya-isimleri.txt

Ya da doğrudan cmd.exe ile

dir /s /b | sort /r /+261 /o longpaths.txt

Öngörülü insanların kullanacağı yöntem ise [1]'de belirtildiği gibi:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem]
"LongPathsEnabled"=dword:00000001

---

[1] https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry

[2] https://www.mindgems.com/article/find-long-paths-long-file-names/

[3] https://it.cornell.edu/shared-file/windows-file-name-or-destination-path-you-specified-not-valid-or-too-long

3.04.2024

Powershell'de USB cihazları listeleme

Linux'taki lsusb komutuna benzer bir şey arıyorum, uzak makinelere Enter-PSSession ile bağlandığımda kullanabileceğim. Şu adresteki çözüm hoşuma gitti:

Get-PnpDevice -PresentOnly | Where-Object { $_.InstanceId -match '^USB' }

 ---

https://learn.microsoft.com/tr-tr/powershell/module/pnpdevice/get-pnpdevice?view=windowsserver2022-ps&wt.mc_id=ps-gethelp