文章目录
[羊城杯 2020]Bytecode
查看题目
python字节码,需要把它转为python代码,如下:
python代码
import dis
def main():
en=[3,37,72,9,6,132]
output=[101,96,23,68,112,42,107,62,96,53,176,179,98,53,67,29,41,120,60,106,51,101,178,189,101,48]
print("welcome to GWHT2020")
flag=raw_input("please input your flag:")
str=flag
a=len(str)
if a>=38:
print('lenth wrong!')
exit(0)
if((((ord(str[0])*2020+ord(str[1]))*2020+ord(str[2]))*2020+ord(str[3]))*2020+ord(str[4]))*2020==1182843538814603:
print('good!continue\xe2\x80\xa6\xe2\x80\xa6')
x=[]
k=5
for i in range(13):
b=ord(str[k])
c=ord(str[k+1])
a11=c^(en[i%6])
a22=b^(en[i%6])
x.append(a11)
x.append(a22)
k+=2
if x==output:
print("good!continue\xe2\x80\xa6\xe2\x80\xa6")
l=len(str)
a1=ord(str[l-7])
a2=ord(str[l-6])
a3=ord(str[l-5])
a4=ord(str[l-4])
a5=ord(str[l-3])
a6=ord(str[l-2])
if a1*3+a2*2+a3*5==1003:
if a1*4+a2*7+a3*9==2013:
if a1+a2*8+a3*2==1109:
if a4*3+a5*2+a6*5==671:
if a4*4+a5*7+a6*9==1252:
if a4+a5*8+a6*2==644:
print('congraduation!you get the right flag!')
字节码解释文章:
https://forgo7ten.github.io/2020/01/28/2020012801/#%E8%B7%B3%E8%BD%AC
https://docs.python.org/zh-cn/3/library/dis.html#python-bytecode-instructions
看了python代码后,紧接着需要用z3约束来进行解答,更加简便
注意点:
BINARY_SUBTRACT 这个是减法
BINARY_SUBSCR 这个是索引
Z3约束脚本
from z3 import *
def main():
s=Solver()
flag=[]
for i in range(5):
flag.append(Int("flag%i"%i))
s.add(((((flag[0] * 2020 + flag[1]) * 2020 + flag[2]) * 2020 + flag[3]) * 2020 +
flag[4]) == 1182843538814603)
for i in range(5):
s.add(flag[i]>30)
s.add(flag[i]<128)
if s.check()==sat:
print(s.model())
en=[3,37,72,9,6,132]
output=[101,96,23,68,112,42,107,62,96,53,176,179,98,53,67,29,41,120,60,106,51,101,178,189,101,48]
ss=Solver()
flag2=[]
j=0
for i in range(13):
flag2.append(output[j+1]^en[i%6])
flag2.append(output[j]^en[i%6])
j+=2
print(flag2)
sss=Solver()
flag3=[]
for i in range(6):
flag3.append(Int("flag3%i"%i))
sss.add((flag3[0]*3+flag3[1]*2+flag3[2]*5)==1003)
sss.add((flag3[0]*4+flag3[1]*7+flag3[2]*9)==2013)
sss.add((flag3[0]*1+flag3[1]*8+flag3[2]*2)==1109)
sss.add((flag3[3]*3+flag3[4]*2+flag3[5]*5)==671)
sss.add((flag3[3]*4+flag3[4]*7+flag3[5]*9)==1252)
sss.add((flag3[3]*1+flag3[4]*8+flag3[5]*2)==644)
for i in range(5):
sss.add(flag3[i]>30)
sss.add(flag3[i]<128)
if sss.check()==sat:
print(sss.model())
if __name__=="__main__":
main()
注意点:
for i in range(13):
flag2.append(output[j+1]^en[i%6])
flag2.append(output[j]^en[i%6])
这里不能当成range(26)来算,因为en下标同一组是一样的
a=[71,87,72,84,123,99,102,97,50,98,56,55,98,51,102,55,52,54,97,56,102,48,97,99,53,99,53,57,54,51,102,97,101,102,102,55,51]
注意最后五个顺序
GWHT{cfa2b87b3f746a8f0ac5c5963faeff73
加上最后一半}
GWHT{cfa2b87b3f746a8f0ac5c5963faeff73}
总结:
此次题目不难,flag分成三部分来看待即可,最主要就是了解python字节码,懂得如何把Python字节码转换成python伪代码,紧接着再来进行下一步的分析
[UTCTF2020]babymips
jeb:
4199924
这玩意是个地址,是我万万没想到的。。。
按下键盘d
后,就转换回地址了,然后即可进行分析
jeb跟ida比起来是真的一言难尽。。。
内部函数,简直一团乱麻。
ida:
ida这玩意分析得多棒,清秀简洁
unsigned char ida_chars[] =
{
0x62, 0x6C, 0x7F, 0x76, 0x7A, 0x7B, 0x66, 0x73, 0x76, 0x50,
0x52, 0x7D, 0x40, 0x54, 0x55, 0x79, 0x40, 0x49, 0x47, 0x4D,
0x74, 0x19, 0x7B, 0x6A, 0x42, 0x0A, 0x4F, 0x52, 0x7D, 0x69,
0x4F, 0x53, 0x0C, 0x64, 0x10, 0x0F, 0x1E, 0x4A, 0x67, 0x03,
0x7C, 0x67, 0x02, 0x6A, 0x31, 0x67, 0x61, 0x37, 0x7A, 0x62,
0x2C, 0x2C, 0x0F, 0x6E, 0x17, 0x00, 0x16, 0x0F, 0x16, 0x0A,
0x6D, 0x62, 0x73, 0x25, 0x39, 0x76, 0x2E, 0x1C, 0x63, 0x78,
0x2B, 0x74, 0x32, 0x16, 0x20, 0x22, 0x44, 0x19
};
a=[
0x62, 0x6C, 0x7F, 0x76, 0x7A, 0x7B, 0x66, 0x73, 0x76, 0x50,
0x52, 0x7D, 0x40, 0x54, 0x55, 0x79, 0x40, 0x49, 0x47, 0x4D,
0x74, 0x19, 0x7B, 0x6A, 0x42, 0x0A, 0x4F, 0x52, 0x7D, 0x69,
0x4F, 0x53, 0x0C, 0x64, 0x10, 0x0F, 0x1E, 0x4A, 0x67, 0x03,
0x7C, 0x67, 0x02, 0x6A, 0x31, 0x67, 0x61, 0x37, 0x7A, 0x62,
0x2C, 0x2C, 0x0F, 0x6E, 0x17, 0x00, 0x16, 0x0F, 0x16, 0x0A,
0x6D, 0x62, 0x73, 0x25, 0x39, 0x76, 0x2E, 0x1C, 0x63, 0x78,
0x2B, 0x74, 0x32, 0x16, 0x20, 0x22, 0x44, 0x19
]
flag=""
for i in range(len(a)):
flag+=chr(a[i]^(i+23))
print(flag)
utflag{mips_cpp_gang_5VDm:~`N]ze;\)5%vZ=C'C(r#$q=*efD"ZNY_GX>6&sn.wF8$v*mvA@'}
总结:
jeb中注意4199924
形式的数据可能是地址
(v2 ^ 78) > 0
这个v2是长度,长度异或78,结果大于0就报错,说明它的长度就等于78(因为相同异或为0,不同异或为1)。。
这点jeb挺好玩的