It is quite simple PRNG with the equation (t = 0xdeadbeef):  x_i = (k_1 - t) x_{i-1} + k_1 t x_{i-2} + k_2 (mod\ k_3)

We can define y_i as y_i = x_i + t x_{i-1}, then y_i = k_1 y_{i-1} + k_2 (mod\ k_3) . So, it’s just same as the normal LCG.

I used the method to break LCG described in this link, and the solver is here.

from pwn import *

def xgcd(b, a):
    x0, x1, y0, y1 = 1, 0, 0, 1
    while a != 0:
        q, b, a = b // a, a, b % a
        x0, x1 = x1, x0 - q * x1
        y0, y1 = y1, y0 - q * y1
    return  b, x0, y0

def mulinv(b, n):
    g, x, _ = xgcd(b, n)
    if g == 1:
        return x % n

r = remote('lcg.eatpwnnosleep.com', 12345)
inputs = []

for i in range(16):
    r.sendline('1')
    inputs.append( int(r.recvuntil('\n')) )

print(inputs)

k = 0xdeadbeef
arr = []

for i in range(15):
    arr.append(inputs[i+1] + k*inputs[i])

# http://sandeepmore.com/blog/2012/03/23/breaking-linear-congruential-generator/
def d(i, j):
    t1 = arr[i] - arr[0]
    t2 = arr[i+1] - arr[1]
    t3 = arr[j] - arr[0]
    t4 = arr[j+1] - arr[1]

    return t1 * t4 - t2 * t3

t = d(2, 3)
for i in range(3, 13):
    t, _, _ = xgcd( t, d(i, i+1) )

k3 = t if t > 0 else -t

print("k3: ", k3)

g0_inv = mulinv( (arr[1] - arr[0]) % k3, k3)
k1 = ((arr[2] - arr[1]) * g0_inv) % k3
k2 = (inputs[2] - (k1 - k) * inputs[1] - k1 * k * inputs[0]) % k3

print("k1: ", k1)
print("k2: ", k2)

s0, s1 = inputs[-2], inputs[-1]

for i in range(16):
    s0, s1 = s1, ( (k1 - k) * s1 + k1 * k * s0 + k2 ) % k3
    r.sendline( str(s1) )

r.interactive()

The flag is SCTF{LCG_is_too_simple_to_be_a_good_CSPRNG}.