In my quest to learn C# I coded this Socks Proxy Server yesterday it complies with Socks Version 4 protocol. Now you can watch the data fly between your applications and its server. Youll need the microsoft .NET compiler version 1.1. to compile this code. After compiling you can setup IE to use the socks server running on ur machine.
Code:
/**
* @Author(s): Leoandru
* @Created: 04/23/2005 (m/d/y)
* @Last Modified: 04/23/2005 By: Leoandru
*
*
* This file is part of a the free software.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THE SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* File Version 1.0
* Microsoft .Net Version 1.1
*/
/// <remarks>
/// SharpSocks is a socks proxy server complying to socks version 4 and 5.
/// </remarks>
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;
namespace Codebox.SharpSocks
{
/// <summary>
/// The SocksServer listen for socks connections determine the client's protocol
/// version and hands off the request accordinly.
/// </summary>
public class SocksServer {
#region variables
protected TcpListener socksserv; //Server Socket
#endregion
#region constructors
/// <summary>
/// Create a socks server instance listening on port "port"
/// </summary>
/// <param name="args">The listening port of the socks server</param>
public SocksServer(Int32 port) : this( CreateEndPoint(port) ) { }
/// <summary>
/// Create a socks server instance bound to the endpoint
/// <param name="ep">The end point to bind to</param>
/// </summary>
public SocksServer(IPEndPoint ep) {
socksserv = new TcpListener(ep);
}
/// <summary>
/// Create a socks server binds to a specific local IPAddress and port number
/// <param name="addr">The IPAddress to bind to</param>
/// <param name="port">The port to bind to</param>
/// </summary>
public SocksServer(IPAddress addr, int port) {
socksserv = new TcpListener(addr, port);
}
#endregion
#region private methods
/// <summary>
/// Create a IPEndPoint from the port.
/// <param name="port">The port to use for the endpoint</param>
/// </summary>
static private IPEndPoint CreateEndPoint(Int32 port) {
IPHostEntry local = Dns.GetHostByName(Dns.GetHostName());
return new IPEndPoint(local.AddressList[0], port);
}
#endregion
#region public methods
public void RunServer() {
socksserv.Start();
Console.WriteLine("socks server started listening on: "+socksserv.LocalEndpoint.ToString());
while(true) {
try {
TcpClient c = socksserv.AcceptTcpClient(); //accept client connect
Console.WriteLine("Connection Accepted: Negotiating Connection...");
NetworkStream ns = c.GetStream();
int version = ns.ReadByte();
Console.WriteLine("Version: {0}", version);
if(version == 4) {
//version 4 protocol handler
Thread thread = new Thread(new ThreadStart(new SocksV4Handler(c).Start));
thread.Start();
}
else if(version == 5) {
//version 5 protocol handler
}
}
catch(Exception e) {
Console.WriteLine(e.StackTrace);
}
}
}
#endregion
static public void Main(string[] args) {
new SocksServer(1080).RunServer();
}
}//SocksServer
/// <summary>
/// Handles socks version 4 protocol
/// </summary>
internal class SocksV4Handler {
#region protected members
//The client connection
protected TcpClient client;
#endregion
#region constructors
public SocksV4Handler(TcpClient c) {
if(c == null) {
throw new ArgumentNullException("tcpclient null");
}
client = c;
}
#endregion
#region public methods
public void Start() {
/*
+----+----+----+----+----+----+----+----+----+----+....+----+
| VN | CD | DSTPORT | DSTIP | USERID |NULL|
+----+----+----+----+----+----+----+----+----+----+....+----+
# of bytes: 1 1 2 4 variable 1
*/
try {
NetworkStream ns = client.GetStream();
int cd = ns.ReadByte(); //the command
byte[] p = new byte[2];
int r = ns.Read(p, 0, p.Length);
if(r != 2) { return; }
int port = GetPort(p);
byte[] ip = new byte[4];
r = ns.Read(ip, 0, ip.Length);
if(r != 4) { return; }
IPAddress address = new IPAddress( GetAddress(ip) );
Console.WriteLine("Connect To Address: "+address.ToString()+"Port: {0}",port);
TcpClient app = new TcpClient();
app.Connect(address, port); //connect to the remote app
Console.WriteLine("Successfuly connected");
//read and discard the rest
while(ns.ReadByte() != 0) { }
//respond to the client
byte[] res = new byte[8];
res[0] = 0;
res[1] = 90;
res[2] = p[0];
res[3] = p[1];
res[4] = ip[0];
res[5] = ip[1];
res[6] = ip[2];
res[7] = ip[3];
ns.Write(res, 0, res.Length);
ns.Flush();
TcpNetworkStreamTunnel t1 = new TcpNetworkStreamTunnel(app, client);
TcpNetworkStreamTunnel t2 = new TcpNetworkStreamTunnel(client, app);
Thread thread1 = new Thread( new ThreadStart(t1.Start) );
Thread thread2 = new Thread( new ThreadStart(t2.Start) );
thread1.Start();
thread2.Start();
}
catch(Exception e) {
Console.WriteLine( e.ToString() );
}
}
/// <summary>
/// Return the specified byte array as an integer.
/// </summary>
private int GetPort(byte[] ba) {
int i = 0;
foreach(byte b in ba) {
i = i << 8;
i |= (int)b;
}
return i;
}
/// <summary>
/// Return the specified byte address as a long.
/// </summary>
private long GetAddress(byte[] ba) {
long l = 0;
for(int i = ba.Length - 1; i >= 0; --i) {
l = l << 8;
l |= (long)ba[i];
}
return l;
}
#endregion
}//SocksV4Handler
internal sealed class TcpNetworkStreamTunnel {
//The stream to read from
private TcpClient input;
//The stream to write to
private TcpClient output;
private byte[] buffer;
public TcpNetworkStreamTunnel(TcpClient input, TcpClient output) {
this.input = input;
this.output = output;
buffer = new byte[49152];
}
public void Start() {
try {
NetworkStream ins = input.GetStream();
NetworkStream outs = output.GetStream();
while(true) {
int read = ins.Read(buffer, 0, buffer.Length);
string data = Encoding.ASCII.GetString(buffer, 0, read);
Console.Write(data);
if(read == 0) { break; }
outs.Write(buffer, 0, read);
outs.Flush();
}
}
catch(Exception) { }
finally {
try {
input.Close();
output.Close();
}
catch(Exception) { }
}
}
}//NetworkStreamTunnel
}
Here is a sample output:
IF you here lots of beeping its the program printing alert characters. You computer won't explode .