While the solution from Sitecore Climber might work for you, another option would be to implement it on your own:
Add an "expirydate" field to your
/sitecore/templates/System/Media/Versioned/File
and
/sitecore/templates/System/Media/Unversioned/File
Templates.
Write a processor for the HttpRequestBegin pipeline where you check if you have a mediaitem and the expirydate field is set to a past date. In case its expired, you can either 404 or redirect to another item. You might want to set the fallback item on the file item, so add another field there and you end up with a nice flexible solution.
The advantage compared to publishing restrictions is that you can get second-precise unpublishing more easily and have a fallback item.