zoukankan      html  css  js  c++  java
  • 萌新带你开车上p站(三)

    本文作者:萌新

    前情回顾:

    萌新带你开车上p站(一)

    萌新带你开车上p站(二)

    0x08


     

    题目给的提示是和运算符优先级有关

     1.png

    登录后直接看源码

    mistake@pwnable:~$ ls
    
    flag  mistake  mistake.c  password
    
    mistake@pwnable:~$ cat mistake.c
    
    #include <stdio.h>
    
    #include <fcntl.h>
    
     
    
    #define PW_LEN 10
    
    #define XORKEY 1
    
     
    
    void xor(char* s, int len){
    
    int i;
    
    for(i=0; i<len; i++){
    
    s[i] ^= XORKEY;
    
    }
    
    }
    
     
    
    int main(int argc, char* argv[]){
    
     
    
     
    
    int fd;
    
    if(fd=open("/home/mistake/password",O_RDONLY,0400) < 0){
    
    printf("can't open password %d
    ", fd);
    
    return 0;
    
    }
    
     
    
    printf("do not bruteforce...
    ");
    
    sleep(time(0)%20);
    
     
    
    char pw_buf[PW_LEN+1];
    
    int len;
    
    if(!(len=read(fd,pw_buf,PW_LEN) > 0)){
    
    printf("read error
    ");
    
    close(fd);
    
    return 0;
    
    }
    
     
    
    char pw_buf2[PW_LEN+1];
    
    printf("input password : ");
    
    scanf("%10s", pw_buf2);
    
     
    
    // xor your input
    
    xor(pw_buf2, 10);
    
     
    
    if(!strncmp(pw_buf, pw_buf2, PW_LEN)){
    
    printf("Password OK
    ");
    
    system("/bin/cat flag
    ");
    
    }
    
    else{
    
    printf("Wrong Password
    ");
    
    }
    
     
    
    close(fd);
    
    return 0;
    
    }
    

    看关键:

    main调用的xor函数: 

    2.png

    将长度给len的字符串与1异或

    main中的主要逻辑 

    3.jpg

    从/home/mistake/password读10个字节数据放到pw_buf,我们手动输入10字节数据放在pw_buf2,如果pw_buf2与1异或的结果如果与pw_buf相等,则打印flag

    那么关键就是pw_buf的数据,先直接读password看看 

    4.png

    没有权限

    题目的提示是和运算符优先级有关

    我们仔细分析源码,看看问题出在哪里

    问题在这里

    if(fd=open("/home/mistake/password",O_RDONLY,0400) < 0){

    open函数里权限检查是没问题的,O_RDONLY表示以只读方式打开

    0400表示文件所有者具有可读取的权限

    由于权限通过检查,所以open函数返回值为0

    有因为0<0不成立

    所有比较结果为0

    然后赋值给fd

    即fd为0,表示标准输入,也就是说fd现在是我们可控的

    结合之前分析,pw_buf也为我们控制

    那就很简单了 

    5.png

    第一次输入10个1,存入pw_buf

    第二次输入10个0,存入pw_buf2,与1异或后覆盖pw_buf2,此时buf2的值也为10个1,满足打印flag的逻辑

     

    0x09shellshock


     

    查看权限 

    6.png

    可以看到shellshock程序的所属组的权限位上有s,表示sgid,也就是说在执行shellshock时,用户将获得shellshcok所属组的权限,即执行shellshock后将获得root所在用户组的权限,而由flag这一行的权限位可知,该权限可以读取flag

    这一点从源码中也可以看出来

    7.png

    getegid()返回进程执行有效组识别码。在这里getegid()返回的就是root所在用户组的id

    setresuid用于设置ruid,euid,seuid,在这里就是统统都设置为进程当前的egid

    setresgid用于设置rgid,egid,sgid,这里也是统统设置为进程当前的egid

    因为s标志,所以egid实际上是root所在用户组的id

    再根据题目提示的shellshock

    这是著名的bash破壳漏洞

    直接在网上找到poc修改下即可 

    8.png

    解释一下发生了什么

    首先在当前环境下定义了X函数,函数体由{}括起来,然后在函数体外加了一条额外的语句/bin/cat ./flag即打印flag的命令,这条语句会在后面执行./shellshock时被调用,由于执行shellshock时会有root权限,所以自然就有权限来打印flag了

    想知道怎么操作吗?点击开始实践——破壳漏洞实践http://www.hetianlab.com/expc.do?ec=ECID172.19.105.222014092915250400001

    9.jpg

    0x10


     

    按照要求连接服务器 

    0.jpg

    这是一个小游戏

    大意是一堆货币里有真币假币,两者重量不同,真币10g,假币9g。给你N个硬币,C次机会,让你猜哪一个是假币。需要在30s的时间里才对100次。

    这题其实考的是算法。

    分治法解决

    举个例子。

    一共100个硬币,其中1个是假的,先称重1-49,如果结果整除10,则假币在50-100.

    第二轮称50-75,如果不整除10,则假币在其中

    第三轮称50-62.。。。。

    其实就是简单的二分法

    编程

    import time
    
    from pwn import *
    
     
    
    conn = remote('0', 9007)
    
    conn.recv(10000)
    
    for _ in range(100)://猜100次
    
        line = conn.recv(1024).decode('UTF-8').strip().split(' ')
    
      print(line)
    
        n = int(line[0].split('=')[1])//读出给的n,c
    
        c = int(line[1].split('=')[1])
    
        left = 0
    
        right = n//共n个硬币
    
     
    
        for _ in range(c)://二分法猜解
    
            guess = ' '.join(str(left) for left in range(left, int((left+right)/2)))
    
            conn.sendline(guess)//给出需要猜测的货币
    
            output = int(conn.recv(1024).decode('UTF-8').strip())//读取返回称重的结果
    
            if (output % 10 == 0)://整除10的情况
    
                left = int((left+right)/2)
    
            else://不整除的情况
    
                right = int((left+right)/ 2)
    
        conn.sendline(str(left))
    
        print(conn.recv(1024).decode('UTF-8'))//打印一轮的结果
    
    print(conn.recv(1024).decode('UTF-8'))
    
    conn.close()
    

    以上一关的shellshock登录服务器,在tmp目录下新建一个python 脚本

    按照提示

    用pwntools编写的时候,注意remote(‘0’,9007)

    执行如下 

    11.png

    12.jpg

    0x11 blackjack 


     

    13.jpg

    em...源码有点长,直接看关键部分 

    14.png

    这里会校验我们输入的金额

    如果比cash大则会报错,并要求再次输入

    不过再次输入的时候不会报错了

    考虑到要赚够1000000,而输的几率比较大

    我们可以输入-的金额,比如-1000000,只要输了就可以拿到flag

    15.jpg

    然后选择y就打印出flag了

    16.png

  • 相关阅读:
    Lua 虚拟机指令
    如何打包和部署air应用程序
    demjson
    mongo批量插入问题(insert_many,bulk_write),spark df转json传入mongo
    python isinstance()方法的使用
    python 时间对应计算
    第三方库-正则re
    第三方库-时间函数dateutil
    Mongodb操作-更新操作符
    python文件操作-1.将PDF转成Excel
  • 原文地址:https://www.cnblogs.com/hetianlab/p/12713989.html
Copyright © 2011-2022 走看看