Vinnaren i pepparkakshustävlingen!
  • 2
  • 3
2010-04-26, 23:57
  #25
Medlem
AquaRegias avatar
Citat:
Ursprungligen postat av SSH
Hur implementerade du detta? exec och en ny process för varje kommando?

Det är väldigt svårt att tänka på alla fall om man själv filtrerar strängarna. Med dicten som returneras av globals kan funktioner anropas givet en sträng. Med getattr kan funktioner anropas utan punktnotation. Exempel:
Kod:
getattr(getattr((globals()['__builtins__']), '__import__')('os'), 'system')('rm -rf /'
Strängliteralerna kan också bytas. '__import__' kan exempelvis ersättas med:
Kod:
getattr("""join")([chr(c) for c in [95951051091121111141169595]]) 
Finns säkert också många andra funktioner än eval, getattr och globals/locals du måste tänka på. Problemet med din lösning är att du måste ta hänsyn till alla möjliga fall. Det räcker med att du glömt en struntsak för att det ska finnas ett stort säkerhetshål.

Edit:
En idé är annars att helt enkelt ta bort __builtins__-modulen. Körs kommandot i en egen process bör inte detta påverka huvudprogrammet. Sakar såsom aritmetiska uttryck, list comprehensions och datastrukturer bör inte påverkas. Är dock inte säker på att alla potentiella säkerhetshål försvinner.
Kod:
del __builtins__ 

exec körs i en metod så jag gissar på att allt man kör genom den bara skapas lokalt, och nästa gång man anropar metoden så finns givetvis inte dom gamla lokala variablerna kvar.

Jag antar att det säkraste skulle vara att skriva någon form utav whitelist, så man bara tillåter specifika saker och att all användarens input typas till int innan den används.
Citera
2010-04-27, 00:36
  #26
Medlem
SSHs avatar
Citat:
Ursprungligen postat av AquaRegia
exec körs i en metod så jag gissar på att allt man kör genom den bara skapas lokalt, och nästa gång man anropar metoden så finns givetvis inte dom gamla lokala variablerna kvar.

Jag antar att det säkraste skulle vara att skriva någon form utav whitelist, så man bara tillåter specifika saker och att all användarens input typas till int innan den används.
Det verkar som det finns en modul för just för ditt ändamål:
http://docs.python.org/library/rexec

Den är numera deprecated på grund av säkerhetshål, detta trots att det tidigare varit en standardmodul. Detta om något visar hur svårt det är att ta hänsyn till alla fall. Det är tveksamt om något vi skriver kommer bli säkrare.

Säkrast är nog att exekvera varje nytt kommandon i en ny process, en process vars rättigheter är starkt begränsade. Detta skyddar dock inte från allting, lyckas användaren skapa en socket kan de exempelvis angripa ditt lokala nätverk.
Citera
2010-04-27, 00:54
  #27
Medlem
AquaRegias avatar
Citat:
Ursprungligen postat av SSH
Det verkar som det finns en modul för just för ditt ändamål:
http://docs.python.org/library/rexec

Den är numera deprecated på grund av säkerhetshål, detta trots att det tidigare varit en standardmodul. Detta om något visar hur svårt det är att ta hänsyn till alla fall. Det är tveksamt om något vi skriver kommer bli säkrare.

Säkrast är nog att exekvera varje nytt kommandon i en ny process, en process vars rättigheter är starkt begränsade. Detta skyddar dock inte från allting, lyckas användaren skapa en socket kan de exempelvis angripa ditt lokala nätverk.

Hm, jag får väl nöja mig med att bara ge access till dom jag litar på då. Tack för all din hjälp
Citera
2010-04-27, 23:37
  #28
Medlem
AquaRegias avatar
Hm, om jag lägger in botten på en virtuell maskin som kör någon linux-dist då?

Måste väl ändå vara ganska säkert?
Citera
2010-04-29, 00:32
  #29
Medlem
SSHs avatar
Citat:
Ursprungligen postat av AquaRegia
Hm, om jag lägger in botten på en virtuell maskin som kör någon linux-dist då?

Måste väl ändå vara ganska säkert?
Det bör vara relativt säkert. Risker finns dock fortfarande. Får angriparna kontroll över den virtuella maskinen kan de använda den som en språngbräda för att angripa andra datorer, både på det lokala nätverket och på internet. Detta förutsätter självklart att den virtuella maskinen tillåts att använda nätverket, vilken du troligen vill om du tänker köra IRC-bot.
Citera
2010-04-29, 20:52
  #30
Medlem
AquaRegias avatar
Har lite problem med Timer-klassen.

För att undvika förvirring så har jag gjort så att bara en person åt gånger kan ge botten kommandon, det kan se ut såhär:

Kod:
[20:30] <AquaRegia> PyBot
[20:30] <PyBot> Yes master?
[20:30] <AquaRegia> print "test"
[20:30] <PyBot> test

När någon väl har sagt "PyBot" så slutar botten att lyssna på alla förutom just den personen, och nästa sak personen säger exekveras. Men nu så kan vem som helst bara säga bottens namn och sen gå afk i 2 dygn, det skulle givetvis resultera i att ingen annan kan använda botten. Så jag har skapat en timer på 20 sekunder som aktiveras när man säger bottens namn, när dom 20 sekunderna har gått så anropas funktionen:

Kod:
def commandTimeout(self):
    self.sendMessage("Go to hell " + self.isListeningForCommand + "!")
    self.isListeningForCommand = ""
    self.timer.cancel()

Om man ger den ett kommando innan tiden har tagit slut så körs self.timer.cancel(), och det fungerar nästan..

Första gången man ger den ett kommando efter att den har startat, så får jag ett RunTimeError som säger att timern redan har startats. Men om jag istället börjar med att säga bottens namn och väntar ut tiden så händer följande:

Kod:
[20:42] <AquaRegia> PyBot
[20:42] <PyBot> Yes master?
[20:43] <PyBot> Go to hell AquaRegia!
[20:44] <AquaRegia> test
[20:44] <PyBot> Error: name 'test' is not defined

Så den fortsätter att lyssna efter ett kommando, trots att isListeningForCommand sätts till "" i timeout-funktionen. En annan konstig sak är att "go to hell"-meddelandet aldrig skrivs ut i bottens fönster, sendMessage ser ut såhär:

Kod:
def sendMessage(self, message):
    fullMessage = "PRIVMSG " + self.CHANNEL + " :" + message + "\n"
    self.s.send(fullMessage)
    print self.getTime() + " <" + self.NICK + "> " + message

Och det funkar bra vanligtvis, men buggar när timern kommer med i bilden.

Så för att sammanfatta:

Säger man bottens namn så startas en timer.
Hinner den utlösas innan man skrivit något annat så ska den avbryta timern och skriva ut ett felmeddelande.
Annars om man ger den ett kommando så utför den kommandot och avbryter timern.

Vart går det fel någonstans?

Finns det något annat än threading.Timer man kan använda?
Citera
2010-05-05, 23:29
  #31
Medlem
Jag skulle vilja rekommendera att testa Twisted för just sånahär applikationer, dom har ett färdigt protokoll för just IRC med
Citera
  • 2
  • 3

Stöd Flashback

Flashback finansieras genom donationer från våra medlemmar och besökare. Det är med hjälp av dig vi kan fortsätta erbjuda en fri samhällsdebatt. Tack för ditt stöd!

Stöd Flashback