50
THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM SERIALISIEREN UND DESERIALISIEREN , Dr. Stefan Schlott BeOne Stuttgart GmbH

THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

  • Upload
    others

  • View
    3

  • Download
    0

Embed Size (px)

Citation preview

Page 1: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

THE DE­SERIALKILLER

SICHERHEITSPROBLEME BEIMSERIALISIEREN UND DESERIALISIEREN

, Dr. Stefan Schlott BeOne Stuttgart GmbH

Page 2: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

ABOUT.TXTStefan Schlott, BeOne Stuttgart GmbH

Java­Entwickler, Scala­Enthusiast, Linux­Jünger

Seit jeher begeistert für Security und Privacy

Page 3: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

WAS WAR PASSIERT

Page 4: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d
Page 5: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

TO THE CRIME SCENE!

Page 6: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d
Page 7: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d
Page 8: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d
Page 9: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d
Page 10: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d
Page 11: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d
Page 12: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

EINORDNUNG

Page 13: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

OWASP KATEGORISIERUNG API Abuse Authentication Vulnerability Authorization Vulnerability Availability Vulnerability

Code Permission Vulnerability Code Quality Vulnerability Configuration Vulnerability

Cryptographic Vulnerability Encoding Vulnerability Environmental Vulnerability Error

Handling Vulnerability General Logic Error Vulnerability Input ValidationVulnerability Logging and Auditing Vulnerability Password Management Vulnerability

Path Vulnerability Protocol Errors Range and Type Error Vulnerability Sensitive Data

Protection Vulnerability Session Management Vulnerability Synchronization and Timing

Vulnerability Unsafe Mobile Code Use of Dangerous API

Page 14: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

SQL INJECTIONFehlende Input­Validierung: SQL­Statement wird direkt

zusammengebaut

name = … // (direkt aus dem Webformular)result = SQL.exec("SELECT * FROM Students WHERE NAME='" + name + "';");

SELECT * FROM Students WHERE NAME='Robert';DROP TABLE Students;­­';

Page 15: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

PERSISTENT CROSS­SITE SCRIPTINGFehlende Input­Validierung…

Page 16: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

PERSISTENT CROSS­SITE SCRIPTING…führt zu JavaScript­Ausführung im Browser

Page 17: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

SERIALISIERTE DATENAuch hier: Vorsicht mit Daten aus unbekannter Quelle!

Unbekannt = Alles von außen ohne Authentisierung

Code­Ausfühung? In Java?

Page 18: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

JAVA SERIALISIERUNG

Page 19: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

SERIALISIERUNGS­101public static void serializeData(String filename) throws … ConferenceSlot data = new ConferenceSlot("The De­Serial Killer", "Stefan Schlott", "Usedom"); try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(filename))) out.writeObject(data);

public static void deserializeData(String filename) throws … try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(filename))) ConferenceSlot data = (ConferenceSlot)in.readObject(); System.out.println(data);

Voraussetzung: ConferenceSlot implementiert Serializable

Page 20: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

SERIALISIERUNG WANDELTOBJEKT IN BYTESTREAM

00000000 ac ed 00 05 73 72 00 18 63 6f 6d 2e 62 65 6f 6e |....sr..com.beon|00000010 65 2e 43 6f 6e 66 65 72 65 6e 63 65 53 6c 6f 74 |e.ConferenceSlot|00000020 7d 69 17 26 40 cc 5f 0f 02 00 03 4c 00 04 72 6f |i.&@._....L..ro|00000030 6f 6d 74 00 12 4c 6a 61 76 61 2f 6c 61 6e 67 2f |omt..Ljava/lang/|00000040 53 74 72 69 6e 67 3b 4c 00 07 73 70 65 61 6b 65 |String;L..speake|00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.|00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d 74 00 |~..xpt..Usedomt.|00000070 0e 53 74 65 66 61 6e 20 53 63 68 6c 6f 74 74 74 |.Stefan Schlottt|00000080 00 14 54 68 65 20 44 65 2d 53 65 72 69 61 6c 20 |..The De-Serial |00000090 4b 69 6c 6c 65 72 |Killer|

Page 21: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

OBJEKT LESENKlasse bestimmen

Instanz erzeugen: Zero­Args­Constructor der ersten nicht­serialisierbaren Superklasse

Daten lesen: Mittels readObject der Klasse, falls vorhanden.Sonst Standardverhalten (rekursiv alle Members, die nicht

transient sind)

Voraussetzung: Benötigte Klassen im Klassenpfad

Page 22: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

EXPLOIT DER DEMO

Page 23: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

„GADGET“ KONSTRUIERENZiel: Programm ausführen

Annahme: Groovy­Bibliothek im Klassenpfad

Page 24: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

Idee: Groovy­Strings haben eine Methode execute, welche denString als Kommando ausführt

Methode als Groovy­Closure verpacken:

MethodClosure payloadClosure = new MethodClosure("/usr/bin/xterm", "execute");

Page 25: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

Suche nach einer Methode, welche eine Closure evaluiert:GString!

GString string = new GStringImpl(new Object[] payloadClosure , new String[] );

Evaluiert Closures nur mit 0 oder 1 Parameter… per Reflection „hinbiegen“

Page 26: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

Suche nach einer Klasse, welche in readObject die MethodetoString aufruft: BadAttributeValueExpException!

BadAttributeValueExpException data = new BadAttributeValueExpException(string);

…oder so ähnlich: So wird toString schon beim Zusammenbauenausgeführt.

Also: Platzhalter setzen und string per Reflection setzen.

Page 27: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

DESERIALISIERUNG1. BadAttributeValueExpException wird gelesen, derenreadObject­Methode gerufen

2. Diese liest string, diese liest payloadClosure(Standardmechanismus)

3. BadAttributeValueExpException::readObject rufttoString von string

4. GStringImpl::toString ruft payloadClosure.call()

Page 28: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d
Page 29: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

VIELFÄLTIGE ANWENDUNGRMI

JMX

JMS­Nachrichten

JSF­Viewstate

Object­Caches, z.B. (anwendungsspezifisch) memcached

Authentisierung hilft nicht zwingend!Beispiel: JMX

Page 30: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d
Page 31: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

AUCH ANDERE SPRACHEN!

Page 32: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

RUBY­ON­RAILS­MELTDOWN…als prominentes Beispiel

(analoges lässt sich mit Python, PHP, etc. darstellen)

Page 33: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

YAML DESERIALIZATION PROBLEMRails­Bug vom Januar 2013

(betroffen: Alles vor 3.2.11, 3.1.10, 3.0.19 und 2.3.15)

Problem: Mittels XML­Markup konnte automatisch ein YAML­Parserangestoßen werden:

<fool type='yaml'>…yaml goes here…</fool>

Page 34: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

YAML: MEHR ALS NUR LESBARE DATENNicht (nur) strukturierte Daten, sondern vollständige Serialisierung!

Mit !klassenname Klasse instantiieren

Syntax Hashmap = Members belegen

Mit !klassenname [ p1, … ] Konstuktorparameter angeben

Page 35: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d
Page 36: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

ANDERE SERIALISIERUNGS­BIBLIOTHEKEN

Page 37: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

YAMLProminente Java­Bibliothek: SnakeYaml

YAML: Objektinstantiierungen, Konstuktorparameter

Kümmert sich nicht um Serializable

Page 38: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

Groovy Expando: Mappt (freie) Methodennamen auf Closures.

Hier: toString auf GString::execute!!groovy.util.Expando [ toString: !!org.codehaus.groovy.runtime.MethodClosure [/usr/bin/xterm, execute] ]

Ein tostring (z.B. Log­Statement) löst Exploit aus

Page 39: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d
Page 40: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

Lösung für SnakeYaml: SafeConstructor limitiert auf BasistypenYaml yaml = new Yaml(new SafeConstructor());

Weitere Klassen können registriert werden

Unglücklicherweise nicht der Default!

Page 41: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

XSTREAM„No mappings required. Most objects can be

serialized without need for specifyingmappings“

Kompatibel mit normaler Java­Serialisierung!

Sogar die Exploits sind kompatibel!

Page 42: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

<?xml version="1.0"?><java.util.PriorityQueue serialization="custom"> <unserializable-parents/> <java.util.PriorityQueue> <default> <size>2</size> <comparator class="org.apache.commons.collections4.comparators.TransformingComparator"> <decorated class="org.apache.commons.collections4.comparators.ComparableComparator"/> <transformer class="org.apache.commons.collections4.functors.InvokerTransformer"> <iMethodName>newTransformer</iMethodName> <iParamTypes/> <iArgs/> </transformer> </comparator> </default> <int>3</int> <com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl serialization="custom"> <com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl>(…)

Page 43: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d
Page 44: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

Lösung für XStream: Restriktion mittels addPermission

Unglücklicherweise nicht der Default!

Viel Handarbeit nötig

Page 45: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

FAZIT

Page 46: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

Die Bibliotheken müssen ihre Probleme fixen!

Page 47: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

Problem nicht neu

Problem nicht Java­typisch

Problem nicht in Apache Commons, Groovy, etc.

Page 48: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

Potentielle Problemquelle: Nicht authentisierte Daten

Potentielle Problemquelle:Jede generische Serialisierungs­Bibliothek

Beschränkung der verwendbaren Klassen

Aber: Java­Serialisierung: Kaum abzudichten

Bibliotheken mit sicheren Defaults verwenden

Page 50: THE DESERIAL KILLER SICHERHEITSPROBLEME BEIM ... · 00000050 72 71 00 7e 00 01 4c 00 05 74 69 74 6c 65 71 00 |rq.~..L..titleq.| 00000060 7e 00 01 78 70 74 00 06 55 73 65 64 6f 6d

BILDQUELLEN (CC) BY Nick kenrick

(CC0) niekverlaan (CC) BY­NC­SA Michele Adami

(CC) BY _Gavroche_ (CC0) condesign

(CC) BY­NC Randall Munroe (CC) BY­NC­SA Canada Science and Technology Museum

(CC0) Pexels (CC) BY­NC­SA Kompania Piwowarska

(CC0) Ramdlon (CC0) Markus Spiske

from the Internet ;)

Attempted murder series Newspaper Murder! Bomb Noodles Exploits of a mum Braille detail for two sided plates Dangerous woman The process of filling bottles Diamond Red Ruby Creative Smartphone Desk Notebook Cat whack­a­mole Not standard usage of standard library