The only way to do this with a validation rule (i.e., without writing code) is to maintain a count of Attachments on the Opportunity. Since the relationship between Attachment and Opportunity is not master-detail, this must be done with customization.
You can write a trigger to do this, but it's easier to do it declaratively by installing Declarative Lookup Rollup Summaries. You can build a rollup using DLRS with the parent object as Opportunity and the child as Attachment; rollup operation as COUNT; any SOQL parameters you need to include; and a target Number field on the Opportunity, such as
Once you do this and go through the activation process for DLRS, including setting the rollup to active and running it in real-time by having DLRS deploy its triggers (you'll probably also want to click Calculate to cover all existing Opportunities), you can write a validation rule on Opportunity something like this:
AND(Count_Of_Attachments__c = 0, ISPICKVAL(StageName, "YOUR_STAGE_NAME_HERE))
This is not a feature that you can get "out of the box". You're going to have to do some real customization to get there, but it's not difficult - you just need to go through several steps and effectively deploy these features to get to your objective.