I don't think it's worth not using a third party gem for this. The problem space is well documented and stable, and most of the libraries are too.
But if you must, it can be done without an external gem. Especially if you're going to constrain yourself to a small subset of file types to "whitelist". The "magic number" pattern for most image files is pretty straightforward once you get the file on your disk:
image = File.new("filename.jpg","r")
irb(main):006:0> image.read(10)
=> "\xFF\xD8\xFF\xE0\x00\x10JFIF"
Marcel, which you linked in your reference, if nothing else, can be a great reference for the magic number sequences you'll need:
MAGIC = [
['image/jpeg', [[0, "\377\330\377"]]],
['image/png', [[0, "\211PNG\r\n\032\n"]]],
['image/gif', [[0, 'GIF87a'], [0, 'GIF89a']]],
['image/tiff', [[0, "MM\000*"], [0, "II*\000"], [0, "MM\000+"]]],
['image/bmp', [[0, 'BM', [[26, "\001\000", [[28, "\000\000"], [28, "\001\000"], [28, "\004\000"], [28, "\b\000"], [28, "\020\000"], [28, "\030\000"], [28, " \000"]]]]]]],
# .....
]