Zj_W1nd's BLOG

2023ciscn决赛awdp复现思路

2025/03/10

CarManager

难点在于数据结构套数据结构,频繁的进行混乱的写入和释放,检查是否出现UAF和溢出比较浪费时间,赛场上估计很容易漏。分为用户-car-comment三套东西的菜单,每个都能删改查并且代码风格不统一。

最显眼的是一个格式化字符串漏洞,但是利用需要过一个challenge,开始看不懂以为是什么简单的对称加密,搜的题的wp也没有这个部分,结果给ai说是个数独,笑了。

第二显眼的是malloc参数取决于用户输入

wp说的UAF觉得是false positive了,堆溢出确实隐蔽,是一个strlen确定size的时候导致的,如果chunk写满了会让strlen变大?可以做溢出

codelog

到处是这种输入谁能保准没问题啊,老老实实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
char __fastcall sub_401536(_BYTE *a1, ssize_t a2)
{
ssize_t v2; // rax

while ( 1 )
{
v2 = a2--;
LOBYTE(v2) = v2 != 0;
if ( !(_BYTE)v2 )
break;
v2 = read(0, a1, 1uLL);
if ( !v2 )
break;
if ( v2 == -1 )
{
if ( *__errno_location() != 11 )
{
LODWORD(v2) = *__errno_location();
if ( (_DWORD)v2 != 4 )
return v2;
}
}
else
{
if ( *a1 == 10 )
{
LOBYTE(v2) = (_BYTE)a1;
*a1 = 0;
return v2;
}
++a1;
}
}
return v2;
}

假的shell,支持9个操作这个程序的sb地方在于似乎逆向存在问题,局部参数在函数内部直接用rbp+0x10和rbp+0x18访问,而64位中间的那些寄存器参数全部弃用了?

1
2
3
4
5
6
7
8
9
.text:00000000004029FF loc_4029FF:                             ; CODE XREF: main+C7↑j
.text:00000000004029FF ; DATA XREF: .rodata:jpt_4029FC↓o
.text:00000000004029FF lea rax, [rbp+var_70] ; jumptable 00000000004029FC case 0
.text:0000000000402A03 push [rbp+var_28]
.text:0000000000402A06 push [rbp+var_30]
.text:0000000000402A09 push [rbp+var_38]
.text:0000000000402A0C push [rbp+var_40]
.text:0000000000402A0F mov rdi, rax
.text:0000000000402A12 call sub_401C2E

有病是吧

已出,题目花里胡哨,但是事实上malloc和free的地方很少,这就带来了一个好处,即我们确定溢出点后,只需要跟踪所有可能的分配和释放就行了,完全不要去逆向程序到底在干嘛(说实话数据结构极其混乱)

定好溢出点之后就在这里打断点,然后用所有其他的东西去给这个溢出点做堆风水,打tcache写freehook一把梭。另外,scanf(%s)出乎意料的能输入\x00,反而会被空格(\x20)截断。

CATALOG
  1. 1. CarManager
  2. 2. codelog