Benutzer-Werkzeuge

Webseiten-Werkzeuge


sec:oracle_log4j_securtiy

Nach Log4j Jars auf dem Betriebsystem suchen

Zwar ist jetzt (01.2021) die ganz große Aufregung rund um log4j https://logging.apache.org/log4j/2.x/ schon wieder etwas abgeklungen, aber es wird trotzdem wichtig bleiben regelmäßig zu prüfen welche Log4J Versionen so auf den Server installiert und evtl. im Einsatz sind.

Siehe dazu ⇒ https://www.bsi.bund.de/DE/Themen/Unternehmen-und-Organisationen/Informationen-und-Empfehlungen/Empfehlungen-nach-Angriffszielen/Webanwendungen/log4j/log4j_node.html

Wichtige Node von Oracle dazu ⇒MOS Article: “Impact of December 2021 Apache Log4j Vulnerabilities on Oracle Products and Services (CVE-2021-44228, CVE-2021-45046)” (Doc ID 2827611.1).

Und es müssen sobald wie möglich die Oracle Critical Patchs January 2022 (siehe ⇒ https://www.oracle.com/security-alerts/cpujan2022.html ) eingespielt werden!

Auch sollten die User Verzeichnisse / PC's im Unternehmen mit durchsucht werden, viele Client Applikationen wie der Oracle SQL Developer verwenden noch angreifbare Versionen, vor allem dann wenn die Software älter als 11.2021 ist.

Nach dem Auffinden lässt sich das Problem auch dadurch beheben, das die Jar Dateien (falls Version 2 » ) mit der neuesten Version ( Upgrade to Log4j 2.3.2 (for Java 6), 2.12.4 (for Java 7), or 2.17.1 (for Java 8 and later) ) https://logging.apache.org/log4j/2.x/download.html ausgetauscht werden , falls noch kein Update für die Software zur Verfügung steht.


Die genaue Version ermitteln

Normalerweise steht die Version auch im Dateinamen, aber nicht immer!

Auch besteht die Gefahr das die Datei umbenannt wurde!

Unter Java ist es normalerweise üblich die Version in der Manifest Datei des Jars zu hinterlegen, das ist zwar auch keine Garantie das das am Ende auch stimmt, aber besser als nichts.

Daher ist ein Ansatz alle Laufwerke nach Log4j zu durchsuchen und in den Jars zu prüfen welche Version das nun sein könnte.

Im besten Fall findet sich die Version im Manifest der Jar Datei:

 Log4J Version über das Manifest ermitteln


Windows

Unter Windows bietet sich die Powershell an, nach den Jars zu suchen, aus diesen die Manifest Datei zu extrahieren und dort die Version auszulesen.

Das Ergebnis wird dann in einer CSV Datei gespeichert und kann ausgewertet werden.

Suchen über die Powershell:

checkJarVersion.ps1
#==============================================================================
# Author: Gunther Pippèrr ( http://www.pipperr.de )
# Desc:   Search for Jar and show the version
# Date:   Jan 2021
# Site:   https://github.com/gpipperr/OraPowerShell
# The code is based on an answers at https://stackoverflow.com/a/37561878/101151
# Check if the version is inside the Jar! 
# & "C:\Program Files\Java\jdk1.8.0_191\bin\jar.exe" xvf junit-4.10.jar META-INF/MANIFEST.MF
# get-content .\META-INF\MANIFEST.MF
#
#==============================================================================
<#
 
  Security:
  (see http://www.pipperr.de/dokuwiki/doku.php?id=windows:powershell_script_aufrufen )
  To switch it off (as administrator)
  get-Executionpolicy -list
  set-ExecutionPolicy -scope CurrentUser RemoteSigned
 
	.NOTES
		Created: 01.2021 : Gunther Pippèrr (c) http://www.pipperr.de
	.SYNOPSIS
		Search for Jar Files and read version
	.DESCRIPTION
		Search for Jar Files and read version over the manifest information
 
	.COMPONENT
		Oracle GPI Script Lib
	.EXAMPLE
		Backup the Database
		.\checkJarVersion.ps1. log4j-core-2.9.1.jar
 
#>
 
param(
    [Parameter(Mandatory=$true)][string]$startDirectory
)
 
 
Add-Type -assembly "system.io.compression.filesystem"
 
$Invocation = (Get-Variable MyInvocation -Scope 0).Value
$scriptpath=Split-Path $Invocation.MyCommand.Path
 
$starttime=get-date
 
#Output File
$logfile_name=$scriptpath+"\search_jar_result_"+$env:COMPUTERNAME+".csv"
 
function searchVersion{
 
	param (
	   [String] $jarfile
	 , [String] $jardir
	 , [String] $jarname
	)
 
	try {
 
		if (![System.IO.File]::Exists($jarfile)) {
			$version=-1
            throw "Jar file ""$jarfile"" not found."
        }
 
		$jar = [io.compression.zipfile]::OpenRead($jarfile)
 
		$file = $jar.Entries  | where-object { $_.Name -eq "MANIFEST.MF"}
 
		if ($file) {
 
			$stream = $file.Open()
			$reader = New-Object IO.StreamReader($stream)
			$text = $reader.ReadToEnd()
			$stream.Close()
 
			$lines =$text -split "`r`n"
			$version_line=$lines |  Select-String -InputObject {$_} -Pattern 'Implementation-Version'
			$version = $version_line -split "`r`n" 
			$version = $version -replace "Implementation-Version:","";
		}
		else {
			$version=-1
		}	
 
		echo "$jardir $jarname $version"
	}
	catch {
	  echo "$jardir $jarname -1"
	}
    finally {
        if ($reader) { $reader.Dispose() }
        if ($jar) { $jar.Dispose() }
    }
}
 
 
# check if \ is missing
if ($startDirectory -notmatch '\\$') {
	$startDirectory += '\'
}
 
$dir_param="$startDirectory"+"log4*.jar"+" /a-d /-c /s /b"
 
 
# Search over the directory
echo "--------------------------------------------------------------"
echo "Start to search for Log4J Jars at $starttime"
echo ""
echo "Parameter startDirectory     : $startDirectory"
echo "Use cmd file search to speed : $dir_param "
echo ""
echo "Write results to             : $logfile_name"
echo "--------------------------------------------------------------"
 
# to slow need 7min to 1 min with cmd
#$files=Get-ChildItem -Path $startDirectory -Include log4*.jar -File -Recurse -ErrorAction SilentlyContinue 
#https://dmfrsecurity.com/2021/08/23/get-childitem-performance/
 
# much better performance 
$files=(cmd /c "dir $dir_param" )
 
#init logfile
echo "Directory JarName Version"> $logfile_name
 
$file_count=0
 
$searchtime=get-date
$duration = [System.Math]::Round(($searchtime- $starttime).TotalMinutes,2)
echo "Start to check Jars at $searchtime - need for search :: $duration Minutes"
echo "--------------------------------------------------------------"
#check jahrs 
 
foreach ( $file in $files ) {
	if ($file) {
		$fpath = Split-Path $file
		$fName = Split-Path $file -Leaf	
 
		echo "Start to check $fName at directory $fpath"
 
		searchVersion -jarfile $file -jardir $fpath -jarname $fName >> $logfile_name
		$file_count=$file_count+1
	}
	else {
		echo "$file is empty"
	}
 
} 
echo "--------------------------------------------------------------"
 
$endtime=get-date
$duration = [System.Math]::Round(($endtime- $starttime).TotalMinutes,2)
 
echo "Finish Search $file_count Jars from  $starttime until $endtime - Duration:: $duration Minutes"
echo "Check $logfile_name for results"
 
echo "-----------------------Finish-------------------------------"

Sollten sich noch Log4J in Wars verstecken, muss hier das ganze nochmal erweitert werden.


Linux

Unter Linux ist das ganze etwas einfacher, auch lässt sich hier das Suche mit „ansible“ ( Mehr zu Ansible siehe Eine Oracle Umgebung mit Ansible warten über alle Linux Server automatisch durchführen.

Suche die Version über die Manifest Datei:

Falls zipgrep verfügbar:

find . -name "YOUR_JAR_FILE.jar" -exec zipgrep "Implementation-Version:" '{}' \;|awk -F ': ' '{print $2}'

Finde log4j jars in wars

Finde alle vorkommen von log4j aus bekannten Anlass in allen Wars auf der aktuellen Maschine

files=`find /. -name "*.war"`
for f in $files 
do 
 echo "$HOSTNAME:$f: " 
 unzip -l $f | grep -i log4j | awk -v host="$HOSTNAME" -v war=$f 'BEGIN { OFS = ":" }{ print host,  war,  $4 }'
done

Ansible Playbook

Einfache Suche nach dem Jar Dateien mit „ansible.builtin.find“ , ermittelte Facts als lokale CSV speichern:

---
- name : Create List of all Log4J Findings
  hosts: all
  vars:
   log_file : "/tmp/find_jars.log"
  tasks:
  - name: check if logfile exits
    ansible.builtin.stat:
     path: "{{ log_file }}"
    register: file_exits_check
    delegate_to: localhost

  - name: Remove file (delete file)
    ansible.builtin.file:
     path: "{{ log_file }}"
     state: absent
    when: file_exits_check.stat.exists
    delegate_to: localhost

  - name: create the file if not extis
    ansible.builtin.file:
     path:  "{{ log_file }}"
     state: touch
    when: not file_exits_check.stat.exists
    delegate_to: localhost

  - name: search for all jars with this name
    become: yes
    become_user: root
    ansible.builtin.find:
     file_type : file
     paths :  "/"
     patterns : "*log4j*"
     recurse: yes
    register: jar_files

  - name: write to local log
    ansible.builtin.lineinfile:
     path: "{{ log_file }}"
     line: "{{ inventory_hostname }}:{{ item.path }}"
     insertafter: EOF
    with_items: "{{ jar_files.files }}"
    delegate_to: localhost

Quellen

Cookies helfen bei der Bereitstellung von Inhalten. Diese Website verwendet Cookies. Mit der Nutzung der Website erklären Sie sich damit einverstanden, dass Cookies auf Ihrem Computer gespeichert werden. Außerdem bestätigen Sie, dass Sie unsere Datenschutzerklärung gelesen und verstanden haben. Wenn Sie nicht einverstanden sind, verlassen Sie die Website. Weitere Information
"Autor: Gunther Pipperr"
sec/oracle_log4j_securtiy.txt · Zuletzt geändert: 2022/01/19 09:30 von gpipperr