Nach der Abfrage

Auch wenn die verarbeiteten Abfragen im Proxy bereits modifiziert wurden, besteht oft der Wunsch, die ermittelten Ergebnisse zu modifizieren oder gegebenenfalls Teilergebnisse zu unterbinden. Ermöglich wird dies durch die Lua-Funktion »read_query_result()« .

Wichtig ist an dieser Stelle, das ohne vorherigen Aufruf der Funktion »read_query()« die Funktion »read_query_result()« nicht aufgerufen wird. So können Ergebnisse in Abhängigkeit zur Append-ID unter Verwendung der Directive »proxy.PROXY_IGNORE_RESULT« wieder aus dem Ergebnis gefiltert werden. Der Code-Ausschnitt in Listing 3 stellt den Zusammenhang zwischen Query-Injection und Änderung des Ergebnisses dar.

Listing 3

add_remove.lua

-- add_remove.lua
function read_query( packet )
        if packet:byte() == proxy.COM_QUERY then
                proxy.queries:append(2, string.char(proxy.COM_QUERY) .. "SELECT NOW()" )
                proxy.queries:append(1, packet )
                proxy.queries:append(2, string.char(proxy.COM_QUERY) .. "SELECT NOW()" )
                return proxy.PROXY_SEND_QUERY
        end
end
function read_query_result(inj)
        if inj.id == 2 then
                for row in inj.resultset.rows do
                        print("injected query returned: " .. row[0])
                end
                return proxy.PROXY_IGNORE_RESULT
        else
                print("query-time: " .. (inj.query_time / 1000) .. "ms")
                print("response-time: " .. (inj.response_time / 1000) .. "ms")
        end
end

Fügt der Datenbankprogrammierr in der ersten Funktion vor dem eigentlichen Befehl ein »select now()« ein, um zum Beispiel entsprechende Performance-Werte zu protokollieren, so entfernt der Proxy dieses Queries in der zweiten Funktion wieder, sodass der Benutzer nichts von diesen Dingen mitbekommt.

Auf diese Weise können Vorgänge transparent innerhalb des Proxies ablaufen – ganz ohne Patch oder Update der vorhandenen Originalversion. Architektonisch betrachtet ist der Proxy nicht die richtige Stelle für die Weiterentwicklung der Datenbankanwendung. Der richtige Eingriffspunkt, um kurzfristigen Fehler zu beheben, ist es auf jeden Fall.

Protokollierung

Bei der Auswertung der Abfrageergebnisse kann die Protokollierung der Abläufe helfen. Da alle Statements über die Funktion »read_query()« zu ermitteln sind, bleiben hier nur die Ausgabeverarbeitung und etwaige Formatierungen zu klären. In den Proxy-Skripts steht dazu der ganze Sprachumfang von Lua zur Verfügung. Das Skript in Listing 4 implementiert eine einfache Log-Datei.

Listing 4

write_logfile.lua

-- write_logfile.lua
 local file_log = 'myproxy.log'
 local fh = io.open(file_log, "a+")
 function read_query( packet )
   if string.byte(packet) == proxy.COM_QUERY then
     local query = string.sub(packet, 2)
     fh:write( string.format("%s %6d -- %s \n",
         os.date('%Y-%m-%d %H:%M:%S'),
         proxy.connection["thread_id"],
         query))
     fh:flush()
   end
 end

Nach Start des Proxies unter Angabe des Lua-Scripts könnte das MySQL-Log so aussehen wie in Listing 5.

Listing 5

Logfile

2008-05-14 15:14:50     30 -- select @@version_comment limit 1
2008-05-14 15:14:53     30 -- SELECT DATABASE()
2008-05-14 15:14:56     31 -- select @@version_comment limit 1
2008-05-14 15:14:59     31 -- select USER()
...

Ähnliche Artikel

comments powered by Disqus

Artikel der Woche

Eigene Registry für Docker-Images

Wer selber Docker-Images herstellt, braucht auch eine eigene Registry. Diese gibt es ebenfalls als Docker-Image, aber nur mit eingeschränkter Funktionalität. Mit einem Auth-Server wird daraus ein brauchbares Repository für Images. (mehr)
Einmal pro Woche aktuelle News, kostenlose Artikel und nützliche ADMIN-Tipps.
Ich habe die Datenschutzerklärung gelesen und bin einverstanden.

Konfigurationsmanagement

Ich konfiguriere meine Server

  • von Hand
  • mit eigenen Skripts
  • mit Puppet
  • mit Ansible
  • mit Saltstack
  • mit Chef
  • mit CFengine
  • mit dem Nix-System
  • mit Containern
  • mit anderer Konfigurationsmanagement-Software

Ausgabe /2021