TL;DR - I think your problem is not related to SSL at all, but you are trying to use a proxy server without the proxy headers.
So, if I use stunnel to create an SSL tunnel, and then pass HTTP traffic through it, would it be the same as using HTTPS normally?
Yes. We use http over stunnel at work to talk to an https-server. That's a workaround for a bug in the Java https client that is not able to talk to an ISS https-server in some situations.
Then, if a proxy/firewall sees only an SSL/TLS connection with encrypted traffic, how could it know the traffic isn't HTTP?
A normal proxy/firewall is not able to tell what is inside.
There are decrypting https-proxies. In order for them to work, they need to trick the client into accepting their own public key instead of the public key of the real server. In https the public key is part of a certificate which contains information about the server name. The certificates are usually signed by CAs, which the browsers know as trustworthy.
The proxy server needs to fake the server certificate in order to get the client to use his own public key. A normal client will display a warning about the invalid certificate. But the proxy can sign the faked certificates with its own CA. And the administrator can install the CA as trusted on the clients.
In theory, I think that if the proxy/firewall can't notice the difference, one should be able to tunnel SSH traffic through an SSL/TLS connection (created with stunnel) instead of HTTP.
The common way to tunnel SSH out even works without the SSL layer on non decrypting https-proxies.
However, in practice, I have seen this not work - the proxy/firewall appears able to detect that it is not HTTPS traffic.
Either you are doing something wrong, or your are behind a decrypting https as explained above.
I think this is why Proxytunnel is used, but I don't understand what Proxytunnel does differently to avoid detection. Does it just create fake HTTP headers?
You have to distinguish between a firewall and a proxy here: If there is just a network firewall you can connect to the target ip-address on port 443 normally. But if there is a proxy, you need to connect to the ip-address and port of the proxy and then tell it to connect to the target using the http protocol. The command is:
CONNECT target:port HTTP/1.1 <cr><lf>
In most cases https-proxy-servers allow connecting to any ip-address but only to port 443. After sending the connect-string, you get a http response header. On a normal https proxy any further information, is forwarded as is into any direction. So you can speak any protocol you want. Using ssh natively from here on works.
In theory a firewall or dumb proxy may prevent this native tunneling by detecting non SSL-traffic. But this is very uncommon. Only a https decrypting proxy will be able prevent this kind of tunnel effectively.