Codeby web-security - новый курс от Codeby Security School

Представляем вашему вниманию новый курс от команды The Codeby - "Тестирование Веб-Приложений на проникновение с нуля". Общая теория, подготовка рабочего окружения, пассивный фазинг и фингерпринт, Активный фаззинг, Уязвимости, Пост-эксплуатация, Инструментальные средства, Social Engeneering и многое другое. Подробнее ...


Как создать веб-сервер с помощью класса HttpListener?

В этой небольшой статье рассмотрим на простом примере, как создать веб-сервер с помощью языка c#, который будет работать в синхронном режиме.

Дано: два компьютера:  (192.168.10.10) и  (192.168.10.1).

Компьютер “A” (клиент) – отправляет запросы веб-серверу с помощью веб-браузера (хром, опера и так далее).

Компьютер “Б” — это веб-сервер, который принимает и обрабатывает входящие запросы, отправленные методами: GET и POST, а так же динамически создаёт html страницу для отправки клиенту в качестве ответа.

Создание веб-сервера

Для начала создадим новый проект типа Windows Forms Application, после чего добавим на форму элемент управления Button (кнопку).

Для создания веб-сервера воспользуемся классом HttpListener из пространства имён System.Net

using System.Net; //добавить
public partial class Form1 : Form
{
HttpListener server;
bool flag = true;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//ресурс, который будет запрашивать пользователь
string uri = @"http://192.168.10.1:8080/say/";
StartServer(uri);
}
private void StartServer(string prefix)
{
server = new HttpListener();
// текущая ос не поддерживается
if (!HttpListener.IsSupported) return;
//добавление префикса (say/)
//обязательно в конце должна быть косая черта
if (string.IsNullOrEmpty(prefix))
throw new ArgumentException("prefix");
server.Prefixes.Add(prefix);
//запускаем север
server.Start();
this.Text = "Сервер запущен!";
//сервер запущен? Тогда слушаем входящие соединения
while (server.IsListening)
{
//ожидаем входящие запросы
HttpListenerContext context = server.GetContext();
//получаем входящий запрос
HttpListenerRequest request = context.Request;
//обрабатываем POST запрос
//запрос получен методом POST (пришли данные формы)
if (request.HttpMethod == "POST")
{
//показать, что пришло от клиента
ShowRequestData(request);
//завершаем работу сервера
if (!flag) return;
}
//формируем ответ сервера:
//динамически создаём страницу
string responseString = @"<!DOCTYPE HTML>
<html><head></head><body>
<form method=""post"" action=""say"">
<p><b>Name: </b><br>
<input type=""text"" name=""myname"" size=""40""></p>
<p><input type=""submit"" value=""send""></p>
</form></body></html>";
//отправка данных клиенту
HttpListenerResponse response = context.Response;
response.ContentType = "text/html; charset=UTF-8";
byte[] buffer = Encoding.UTF8.GetBytes(responseString);
response.ContentLength64 = buffer.Length;
using (Stream output = response.OutputStream)
{
output.Write(buffer, 0, buffer.Length);
}
}
}
private void ShowRequestData(HttpListenerRequest request)
{
//есть данные от клиента?
if (!request.HasEntityBody) return;
//смотрим, что пришло
using (Stream body = request.InputStream)
{
using (StreamReader reader = new StreamReader(body))
{
string text = reader.ReadToEnd();
//оставляем только имя
text = text.Remove(0, 7);
//преобразуем %CC%E0%EA%F1 -> Макс
text = System.Web.HttpUtility.UrlDecode(text, Encoding.UTF8);
//выводим имя
MessageBox.Show("Ваше имя: " + text);
flag = true;
//останавливаем сервер
if (text == "stop")
{
server.Stop();
this.Text = "Сервер остановлен!";
flag = false;
}
}
}
}
}
}

Метод StartServer &#8212; запускает сервер, принимает входящие запросы, отправленные методами: GET или POST на uri адрес: http://192.168.10.1:8080/say. А также создаёт динамическую страницу, которая содержит форму с текстовым полем и кнопкой типа Submit для отправки клиенту.


Paranoid - курс от Codeby Security School

Представляем вашему вниманию курс от команды codeby - "Комплекс мер по защите персональных данных, анонимности в интернете и не только" Подробнее ...


Для вызова метода Start требуются права администратора (запустить Visual Studio от имени Администратора), иначе возникает ошибка Отказано в доступе”.

Метод ShowRequestData обрабатывает http запросы, отправленные методом POST, и выводит введённое имя. Если клиент отправляет слово stop, то веб-сервер приостанавливает свою работу. Если вместо метода Stop вызвать метод Close, то сервер полностью завершит свою работу.

Запуск сервера

1. Запускаем веб-сервер, нажав на кнопку Запустить.

кнопка

2. На клиенте открывает любой доступный веб-браузер, и в адресной строке вводим адрес нужного нам ресурса, в результате появиться форма. Вводим имя и нажимаем на кнопку.

веб-браузер

3. На сервере появляется сообщение, которое содержит введенное имя.

messagebox

4. Для остановки сервера отправляем слово stop (можно заменить любым другим).

текстовое поле

форма

Порт в строке uri является необязательным, если он не указывается, то (по умолчанию) будет использоваться порт 80.

//клиент будет обращаться к данному адресу
string uri = @"http://192.168.10.1/say";

Если указывается порт, то ip адрес или имя хоста (в строке uri) можно не указывать, а заменить его знаком плюс (+).

//сервер принимает все запросы на порт 8080
string uri = @"http://+:8080/";

Теперь на клиенте достаточно ввести только имя или ip адрес сервера и номер порта.

http://192.168.10.1:8080

Как вернуть значение клиенту?

1. Создадим поле name типа string, в котором будет храниться возвращаемое пользователю значение.

bool flag = true;
string name;

2. В методе ShowRequestData вместо либо после вызова метода MessageBox.Show присвоим переменной name значение, которое было передано клиентом.

MessageBox.Show("Ваше имя: " + text);
name = text;

3. В методе StartServer добавим возможность возврата полученного значения.

string htmlpage = @"<!DOCTYPE HTML>
<html><head></head><body>
<form method=""post"" action=""say"">
<p><b>Name: {0}</b><br>
<input type=""text"" name=""myname"" size=""40""></p>
<p><input type=""submit"" value=""send""></p>
</form></body></html>";
string responseString = string.Format(htmlpage, name);

поле формы

Читайте также:


Codeby Market от Сodeby

Мы запустили свой магазин CodebyMarket Equipment for InfoSec. Уже добавили RaspberryAlfa Long-RangeOrange PiArduino и многое другое. Купить Pentesting Devices