生活随笔
收集整理的這篇文章主要介紹了
安恒5月赛BJDCTF3th-逆向
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
0x01.ViQinère - 100
簡單執(zhí)行一下,這是刮開有獎(jiǎng)嗎?(菜.jpg) 題目有靶機(jī),然后就不知道怎么辦。nc連接,就可回彈出密文。
> ncat
183.129 .189 .60 10087
Flag was encrypted by http
: / / cc
. TaQini
. space
.
Output
: FQD
{ GfjuJ5UbLrWjZjpvErXkiAZzlvO0xTa
! cwnLLAsy3B0iEvEy
}
IDA打開main函數(shù) 加密函數(shù)sub_1249 得出腳本
def
handle ( c
) : if ord ( 'a' ) <= ord ( c
) <= ord ( 'z' ) : return ord ( c
) - ord ( 'a' ) elif
ord ( 'A' ) <= ord ( c
) <= ord ( 'Z' ) : return ( ord ( c
) - ord ( 'A' ) ) ^ 0xFFFFFF80 else : return coutput
= "FQD{GfjuJ5UbLrWjZjpvErXkiAZzlvO0xTa!cwnLLAsy3B0iEvEy}"
flag
= ''
alphabet1
= [ ]
alphabet2
= [ ]
box
= 'TaQini'
for i in
range ( ord ( 'a' ) , ord ( 'z' ) + 1 ) : #python包前不包后alphabet1
. append ( i
) #創(chuàng)建a
- z的列表
alphabet1
. reverse ( ) #列表反轉(zhuǎn)
for i in
range ( ord ( 'A' ) , ord ( 'Z' ) + 1 ) : alphabet2
. append ( i
)
alphabet2
. reverse ( )
# print(alphabet1)
v5
= 0
for i
, c in
enumerate ( output
) : if ord ( 'a' ) <= ord ( c
) <= ord ( 'z' ) : index
= - 1 for j in
range ( 26 ) : if alphabet1
[ j
] == ord ( c
) : index
= j
break tmp
= handle ( box
[ v5
& 5 ] ) & 0x7f v5
+ = 1 if index
>= tmp
: flag
+ = chr ( ord ( 'a' ) + index
- tmp
) else : flag
+ = chr ( ord ( 'a' ) + index
- tmp
+ 26 ) elif
ord ( 'A' ) <= ord ( c
) <= ord ( 'Z' ) : index
= - 1 for j in
range ( 26 ) : if alphabet2
[ j
] == ord ( c
) : index
= j
break tmp
= handle ( box
[ v5
& 5 ] ) & 0x7f v5
+ = 1 if index
> tmp
: flag
+ = chr ( ord ( 'A' ) + index
- tmp
) else : flag
+ = chr ( ord ( 'A' ) + index
- tmp
+ 26 ) else : flag
+ = c
print ( flag
)
作為一個(gè)簽到題,有簡單做法,nc連接上后的得到密文,在程序相同目錄下創(chuàng)建一個(gè)flag.txt,寫入密文,控制臺(tái)再執(zhí)行,就會(huì)輸出flag。
0x02.MiscVm
vm題,IDA 找opcode(那個(gè)字符對(duì)應(yīng)那個(gè)功能),找要執(zhí)行的字符排列,分析得到虛擬機(jī)在干什么,逆向?qū)懗瞿_本。
opcode
= [ 3 , 6 , 5 , 4 , 5 , 11 , 1 , 7 , 9 , 5 , 3 , 6 , 10 , 9 , 5 , 4 , 11 , 1 , 6 , 3 , 7 , 9 , 10 , 9 , 5 , 4 , 14 , 1 , 7 , 9 , 10 , 9 , 4 , 5 , 3 , 6 , 1 , 5 , 3 , 6 , 7 , 9 , 10 , 9 , 36 , 3 , 6 , 36 , 4 , 1 , 5 , 7 , 9 , 3 , 6 , 5 , 10 , 9 , 4 , 1 , 7 , 9 , 10 , 9 , 5 , 4 , 5 , 1 , 5 , 7 , 9 , 5 , 10 , 9 , 3 , 6 , 5 , 4 , 5 , 11 , 1 , 7 , 9 , 5 , 3 , 6 , 10 , 9 ]
v15
= [ 0x42 , 0x4a , 0x44 , 0x7b , 0x33 , 0x370 , 0x46 , 0xd4 , 0x3c , 0x610 , 0x4f , 0xc8 , 0x6c , 0x320 , 0x1e , 0x190 , 0x6f , 0x630 , 0x46 , 0x190 , 0x3b , 0x610 , 0x1d , 0xc4 , 0x3e , 0x660 , 0x4b , 0xd0 , 0x6c , 0x310 , 0x46 , 0x188 , 0x33 , 0x370 , 0x4c , 0xcc , 0x7d ]
v10
= 0
v9
= 4
v11
= 128
v12
= 37
v13
= 9999
while v10
< len ( opcode
) : v3
= opcode
[ v10
] if v3
== 1 : v15
[ v9
] //= 16 v9
+= 1 v10
+= 1 continue if v3
== 2 : v15
[ v9
] -= 128 v15
[ v9
] //= v9v11
+= 1 v10
+= 1 continue if v3
== 3 : v15
[ v9
] //= 10 v9
-= 1 v10
+= 1 continue if v3
== 4 : v15
[ v9
] ^ = 0xA v9
+= 1 v12
-= 1 v10
+= 1 continue if v3
== 5 : v10
+= 1 continue if v3
== 6 : v9
+= 1 v15
[ v9
] *= 10 v10
+= 1 continue if v3
== 7 : v15
[ v9
] -= 128 v15
[ v9
] = ~ v15
[ v9
] v10
+= 1 continue if v3
== 8 : v15
[ v9
] += 1 v15
[ v9
] -= v13v9
+= 1 v10
+= 1 v13
= v13
% 1234 - 2019 continue if v3
== 9 : v9
+= 1 v10
+= 1 continue if v3
== 0xA : v10
+= 1 v15
[ v9
] //= 4 continue if v3
== 0xB : v10
+= 1 continue if v3
== 0xC : v9
+= 1 v10
+= 1 v15
[ v9
] += 32 v15
[ v9
] ^ = 0x22 v10
+= 1
indexs1
= [ 1 , 2 , 3 , 4 , 19 , 31 , 25 , 14 , 23 , 33 , 13 , 9 , 24 , 6 , 26 , 34 , 17 , 10 , 8 , 29 , 12 , 15 , 22 , 11 , 18 , 16 , 32 , 28 , 21 , 36 , 20 , 7 , 5 , 27 , 30 , 35 , 37 ]
indexs2
= [ 1 , 2 , 3 , 4 , 31 , 29 , 7 , 35 , 14 , 21 , 9 , 16 , 27 , 18 , 25 , 10 , 20 , 15 , 17 , 22 , 28 , 26 , 36 , 33 , 32 , 5 , 8 , 12 , 23 , 34 , 13 , 30 , 24 , 11 , 19 , 6 , 37 ]
for i
in range ( 37 ) : indexs1
[ i
] -= 1 indexs2
[ i
] -= 1 tmp
= [ 0 for i
in range ( 37 ) ]
flag
= [ 0 for i
in range ( 37 ) ]
for i
, c
in enumerate ( indexs2
) : tmp
[ c
] = v15
[ i
]
for i
, c
in enumerate ( indexs1
) : flag
[ c
] = tmp
[ i
]
flag
= '' . join
( [ chr ( i
) for i
in flag
] )
flag
= flag
[ : 4 ] + flag
[ 20 : 36 ] + flag
[ 4 : 20 ] + flag
[ - 1 ]
print ( flag
)
記錄一個(gè)提取長數(shù)組的python提取辦法:
addr
= 0x203020
ans
= [ ]
for i
in range ( 37 ) : tmp
= hex ( Dword
( addr
+ i
* 4 ) ) print ( tmp
) ans
. append
( tmp
[ : - 1 ] )
print ans
idc腳本提取辦法:
auto addr
= 0x203020 ;
auto x
, i
; for ( i
= 0 ; i
< 37 ; i
++ ) { x
= dword ( addr
) ; Message ( "0x%x," , x
) ; addr
= addr
+ 4 ;
}
總共原程序有四個(gè)函數(shù),第一個(gè)長度+首尾字母,第二個(gè)片段變換,第三個(gè)兩張表互換,第四個(gè)vm,其余是賦值操作,不用管,逆向四個(gè)函數(shù)寫出上面的腳本。
0x03.blink
打開之后閃瞎,很多*號(hào)在閃,色塊是方塊,給人一種二維碼的感覺。所有閃的星疊加在一起就是一個(gè)二維碼。 想到打印所有星號(hào),星號(hào)疊加就是二維碼,IDA打開,紅框函數(shù)打印星號(hào),籃框部分遮蓋色塊取隨機(jī)數(shù),給你搗亂的。腳本復(fù)現(xiàn)紅框函數(shù)的條件即可。由于二維碼正方形,長寬是25比較合理,y方向取50就是只有偶數(shù)符合條件。
unk2004
= [ 0xB1 , 0xB3 , 0xB5 , 0xB7 , 0xB9 , 0xBB , 0xBD , 0xA5 , 0xAB , 0xAD , 0x95 , 0x97 , 0x99 , 0x9B , 0x9D , 0x9F , 0x81 , 0x00 ]
unk2016
= [ 0xB1 , 0xBD , 0xA1 , 0xA3 , 0xA5 , 0xA7 , 0xAD , 0xAF , 0x95 , 0x81 , 0x00 ]
unk2021
= [ 0xB1 , 0xB5 , 0xB7 , 0xB9 , 0xBD , 0xA1 , 0xA7 , 0xAF , 0x91 , 0x95 , 0x99 , 0x9B , 0x9D , 0x81 , 0x00 ]
unk2030
= [ 0xB1 , 0xB5 , 0xB7 , 0xB9 , 0xBD , 0xA3 , 0xA5 , 0xA7 , 0xA9 , 0xAB , 0xAD , 0x95 , 0x99 , 0x9B , 0x9D , 0x81 , 0x00 ]
unk2041
= [ 0xB1 , 0xB5 , 0xB7 , 0xB9 , 0xBD , 0xA1 , 0xA5 , 0xAB , 0xAD , 0x91 , 0x95 , 0x99 , 0x9B , 0x9D , 0x81 , 0x00 ]
unk2051
= [ 0xB1 , 0xBD , 0xA1 , 0xA9 , 0xAB , 0xAF , 0x95 , 0x81 , 0x00 ]
unk205a
= [ 0xB1 , 0xB3 , 0xB5 , 0xB7 , 0xB9 , 0xBB , 0xBD , 0xA1 , 0xA5 , 0xA9 , 0xAD , 0x91 , 0x95 , 0x97 , 0x99 , 0x9B , 0x9D , 0x9F , 0x81 , 0x00 ]
unk206e
= [ 0xA1 , 0xA3 , 0xA5 , 0xA7 , 0xA9 , 0xAD , 0x00 ]
unk2075
= [ 0xB1 , 0xB3 , 0xB7 , 0xBD , 0xBF , 0xA3 , 0xA7 , 0xAD , 0xAF , 0x91 , 0x95 , 0x97 , 0x99 , 0x9D , 0x9F , 0x00 ]
unk2085
= [ 0xB1 , 0xB7 , 0xA1 , 0xA5 , 0xAD , 0xAF , 0x91 , 0x93 , 0x9F , 0x00 ]
unk208f
= [ 0xB3 , 0xB5 , 0xBB , 0xBD , 0xBF , 0xA1 , 0xA5 , 0x91 , 0x93 , 0x9F , 0x81 , 0x00 ]
unk209b
= [ 0xB1 , 0xB3 , 0xB9 , 0xBB , 0xBF , 0xA1 , 0xA3 , 0xA5 , 0xA7 , 0xA9 , 0xAB , 0xAF , 0x97 , 0x81 , 0x00 ]
unk20aa
= [ 0xB3 , 0xB7 , 0xB9 , 0xBD , 0xA1 , 0xA5 , 0xA7 , 0x93 , 0x95 , 0x99 , 0x9B , 0x00 ]
unk20b6
= [ 0xBB , 0xBF , 0xA3 , 0xA5 , 0xA7 , 0xA9 , 0xAB , 0x91 , 0x93 , 0x97 , 0x9B , 0x9F , 0x00 ]
unk20c3
= [ 0xB1 , 0xB5 , 0xB7 , 0xBD , 0xA1 , 0xA3 , 0xA7 , 0xAD , 0x95 , 0x99 , 0x9B , 0x81 , 0x00 ]
unk20d0
= [ 0xB3 , 0xB5 , 0xB9 , 0xBB , 0xBF , 0xA7 , 0xA9 , 0xAB , 0x91 , 0x99 , 0x9F , 0x81 , 0x00 ]
unk20dd
= [ 0xB1 , 0xB3 , 0xB5 , 0xB7 , 0xBB , 0xBD , 0xBF , 0xA1 , 0xA3 , 0xA9 , 0xAD , 0x91 , 0x93 , 0x95 , 0x97 , 0x99 , 0x9B , 0x81 , 0x00 ]
unk20f0
= [ 0xA1 , 0xA5 , 0xA9 , 0xAB , 0x91 , 0x99 , 0x00 ]
unk20f7
= [ 0xB1 , 0xB3 , 0xB5 , 0xB7 , 0xB9 , 0xBB , 0xBD , 0xA1 , 0xA3 , 0xA9 , 0xAD , 0x91 , 0x95 , 0x99 , 0x9D , 0x9F , 0x81 , 0x00 ]
unk2109
= [ 0xB1 , 0xBD , 0xA5 , 0xA7 , 0xA9 , 0xAD , 0x91 , 0x99 , 0x9D , 0x9F , 0x00 ]
unk2114
= [ 0xB1 , 0xB5 , 0xB7 , 0xB9 , 0xBD , 0xA5 , 0xA9 , 0xAD , 0x91 , 0x93 , 0x95 , 0x97 , 0x99 , 0x9B , 0x9D , 0x9F , 0x81 , 0x00 ]
unk2126
= [ 0xB1 , 0xB5 , 0xB7 , 0xB9 , 0xBD , 0xA1 , 0xA3 , 0xA7 , 0xA9 , 0xAB , 0xAD , 0xAF , 0x97 , 0x9F , 0x81 , 0x00 ]
unk2136
= [ 0xB1 , 0xB5 , 0xB7 , 0xB9 , 0xBD , 0xA3 , 0xA5 , 0xA9 , 0xAB , 0xAF , 0x93 , 0x95 , 0x99 , 0x9B , 0x9D , 0x81 , 0x00 ]
unk2147
= [ 0xB1 , 0xBD , 0xA1 , 0xA3 , 0xA9 , 0xAB , 0xAD , 0x93 , 0x95 , 0x99 , 0x9B , 0x00 ]
unk2153
= [ 0xB1 , 0xB3 , 0xB5 , 0xB7 , 0xB9 , 0xBB , 0xBD , 0xA1 , 0xA3 , 0xA5 , 0xAF , 0x91 , 0x93 , 0x99 , 0x9B , 0x9F , 0x81 , 0x00 ] off_4060
= [ unk2004
, unk2016
, unk2021
, unk2030
, unk2041
, unk2051
, unk205a
, unk206e
, unk2075
, unk2085
, unk208f
, unk209b
, unk20aa
, unk20b6
, unk20c3
, unk20d0
, unk20dd
, unk20f0
, unk20f7
, unk2109
, unk2114
, unk2126
, unk2136
, unk2147
, unk2153
] def sa ( i
, j
) : for index
in range ( len ( off_4060
[ i
] ) - 1 ) : if j
== off_4060
[ i
] [ index
] ^ 0xB1 : return True return False from PIL
import Imagex
= 25
y
= 25 im
= Image
. new
( "RGB" , ( x
, y
) )
for i
in range ( 25 ) : for j
in range ( 0 , 50 , 2 ) : if sa
( i
, j
) : im
. putpixel
( ( i
, j
// 2 ) , ( 0 , 0 , 0 ) ) else : im
. putpixel
( ( i
, j
// 2 ) , ( 255 , 255 , 255 ) ) im
. save
( 'flag.png' )
0x04.BScript
給了這么多程序,考察“多合一”,打開0.exe,upx的殼,輸入可以找到熟悉的MZ(PE文件的開頭),結(jié)合經(jīng)驗(yàn)可知803個(gè)程序的輸入又可以組成一個(gè)完整的可執(zhí)行程序。 此題考察批量處理腳本的編寫 批量脫殼: 提前把upx.exe放到803程序相同目錄
import subprocessfile_path
= 'D:\\CTF試題\\0522\\BScript\\BScript\\'
for i
in range ( 0 , 804 ) : command
= 'upx' + ' -d ' + file_path
+ str ( i
) + '.exe' print ( command
) p
= subprocess
. Popen
( command
, shell
= True ) p
. wait
( )
觀察程序的大小可以發(fā)現(xiàn),這里面一共有兩種,一種是讀取0x40個(gè)字節(jié),按照倒序進(jìn)行對(duì)比,另一種是讀取0x20個(gè)字節(jié),按照正序?qū)Ρ?#xff0c;腳本提取隱藏程序。
import os
def get_FileSize ( filePath
) : fsize
= os
. path
. getsize
( filePath
) return fsize
program
= b
""
script
= b
""
for i
in range ( 804 ) : if get_FileSize
( './%d.exe' % i
) == 48643 : with open ( './%d.exe' % i
, 'rb' ) as f
: f
. read
( 0x403040 ) ff
= list ( f
. read
( 0x40 ) ) ff
. reverse
( ) program
+= bytes ( ff
) elif get_FileSize
( './%d.exe' % i
) == 48625 : with open ( './%d.exe' % i
, 'rb' ) as f
: f
. read
( 0x403020 ) ff
= list ( f
. read
( 0x20 ) ) program
+= bytes ( ff
) else : print ( get_FileSize
( '%d.exe' % i
) )
with open ( 'easy.exe' , 'wb+' ) as f
: f
. write
( program
)
得到easy.exe,ida打開搜索字符串,找到判斷,發(fā)現(xiàn)兩段拼接的結(jié)果QkpEe1doT3RfNF9iYWV1dDFmdTFfc2NybHB0fQAA,再找算法,發(fā)現(xiàn)base64的加密數(shù)組最終得到BJD{WhOt_4_baeut1fu1_scrlpt}
0x05.Py2
以前pyc,現(xiàn)在pyo,直接上網(wǎng)站http://tools.bugscaner.com/decompyle/ emmm,因源文件丟失在此只做一個(gè)思路記錄。 網(wǎng)站反編譯出源碼,可知密碼是bjd3,輸入密碼后程序?qū)ibc.so解密,libc.so提供check函數(shù)對(duì)兩段flag和password加密,分辨出TEA算法
import ctypes
from base64
import b64encode
, b64decode
def decode ( ) : fd
= open ( './libc.so' , 'rb' ) data
= fd
. read
( ) fd
. close
( ) fd
= open ( './libc.so' , 'wb' ) fd
. write
( b64decode
( data
) ) fd
. close
( ) def check ( ) : if b64encode
( pwd
) == 'YmpkMw==' : decode
( ) dl
= ctypes
. cdll
. LoadLibrarylib
= dl
( './libc.so' ) reply
= lib
. checkreply
( int ( flag
[ : length
// 2 ] , 16 ) , int ( flag
[ length
// 2 : ] , 16 ) , int ( pwd
. encode
( 'hex' ) , 16 ) ) print 'your input is BJD{%s}' % flag
. decode
( 'hex' ) else : print 'your password is wrong!' if __name__
== '__main__' : print 'Please input your flag:' flag
= raw_input ( ) flag
= flag
. encode
( 'hex' ) length
= len ( flag
) print 'Please input your password:' pwd
= raw_input ( ) check
( )
TEA算法腳本
using namespace std
; int main
( ) { unsigned
long long v4
; // [ rsp
+ 18h
] [ rbp
- 48h
] unsigned
long long v5
; // [ rsp
+ 20h
] [ rbp
- 40h
] unsigned
long a2
[ 4 ] = { 0x626a6433 , 0x626a6433 , 0x626a6433 , 0x626a6433 } ; v5
= 0xD760262509C2F6D0 ; v4
= 0xAF9D869B6947017D ; unsigned
long long delta
= 0x9E3779B9 ; unsigned
long long sum = 0 ; for ( int i
= 0 ; i
< 32 ; i
+ + ) { sum += delta
; } for ( int i
= 0 ; i
< 32 ; i
+ + ) { v5
-= ( v4
+ sum ) ^ ( ( v4
* 16 ) + a2
[ 2 ] ) ^ ( ( v4
>> 5 ) + a2
[ 3 ] ) ; v4
-= ( v5
+ sum ) ^ ( ( v5
* 16 ) + a2
[ 0 ] ) ^ ( ( v5
>> 5 ) + a2
[ 1 ] ) ; sum -= delta
; sum & = 0xffffffffffffffff ; } cout
<< hex << v4
<< endl
; cout
<< hex << v5
<< endl
; return 0 ;
}
轉(zhuǎn)成字符串 got_tea!
0x06.log1cal
這個(gè)題目都可以當(dāng)自己的參賽id了(手動(dòng)滑稽.png) IDA反編譯出來了很多函數(shù),邏輯也不清楚,經(jīng)分析師傅們的wp,輸入格式為BJD{}的flag,中間部分共64位,分為8個(gè)QWORD,找到關(guān)鍵函數(shù)。
__int64 __fastcall sub_4019EA
( __int64 a1
, __int64 a2
, __int64 a3
, _QWORD
* a4
)
{ signed
int i
; // [ rsp
+ 8h
] [ rbp
- 8h
] unsigned __int8 v6
; // [ rsp
+ Fh
] [ rbp
- 1h
] v6
= 0 ; for ( i
= 0 ; i
<= 63 ; + + i
) { * a4
= a4
[ 1 ] & ~ ( ( ( * a4
<< 28 ) & ~ ( ( * a4
>> 36 ) & ( * a4
<< 28 ) ) | ~ ( ( * a4
>> 36 ) & ( * a4
<< 28 ) ) & ( * a4
>> 36 ) ) & a4
[ 1 ] ) | ~ ( ( ( * a4
<< 28 ) & ~ ( ( * a4
>> 36 ) & ( * a4
<< 28 ) ) | ~ ( ( * a4
>> 36 ) & ( * a4
<< 28 ) ) & ( * a4
>> 36 ) ) & a4
[ 1 ] ) & ( ( * a4
<< 28 ) & ~ ( ( * a4
>> 36 ) & ( * a4
<< 28 ) ) | ~ ( ( * a4
>> 36 ) & ( * a4
<< 28 ) ) & ( * a4
>> 36 ) ) ; a4
[ 1 ] = a4
[ 2 ] & ~ ( ( ( a4
[ 1 ] << 22 ) & ~ ( ( a4
[ 1 ] >> 42 ) & ( a4
[ 1 ] << 22 ) ) | ~ ( ( a4
[ 1 ] >> 42 ) & ( a4
[ 1 ] << 22 ) ) & ( a4
[ 1 ] >> 42 ) ) & a4
[ 2 ] ) | ~ ( ( ( a4
[ 1 ] << 22 ) & ~ ( ( a4
[ 1 ] >> 42 ) & ( a4
[ 1 ] << 22 ) ) | ~ ( ( a4
[ 1 ] >> 42 ) & ( a4
[ 1 ] << 22 ) ) & ( a4
[ 1 ] >> 42 ) ) & a4
[ 2 ] ) & ( ( a4
[ 1 ] << 22 ) & ~ ( ( a4
[ 1 ] >> 42 ) & ( a4
[ 1 ] << 22 ) ) | ~ ( ( a4
[ 1 ] >> 42 ) & ( a4
[ 1 ] << 22 ) ) & ( a4
[ 1 ] >> 42 ) ) ; a4
[ 2 ] = a4
[ 3 ] & ~ ( ( ( a4
[ 2 ] << 16 ) & ~ ( ( a4
[ 2 ] >> 48 ) & ( a4
[ 2 ] << 16 ) ) | ~ ( ( a4
[ 2 ] >> 48 ) & ( a4
[ 2 ] << 16 ) ) & ( a4
[ 2 ] >> 48 ) ) & a4
[ 3 ] ) | ~ ( ( ( a4
[ 2 ] << 16 ) & ~ ( ( a4
[ 2 ] >> 48 ) & ( a4
[ 2 ] << 16 ) ) | ~ ( ( a4
[ 2 ] >> 48 ) & ( a4
[ 2 ] << 16 ) ) & ( a4
[ 2 ] >> 48 ) ) & a4
[ 3 ] ) & ( ( a4
[ 2 ] << 16 ) & ~ ( ( a4
[ 2 ] >> 48 ) & ( a4
[ 2 ] << 16 ) ) | ~ ( ( a4
[ 2 ] >> 48 ) & ( a4
[ 2 ] << 16 ) ) & ( a4
[ 2 ] >> 48 ) ) ; a4
[ 3 ] = a4
[ 4 ] & ~ ( ( ( a4
[ 3 ] << 58 ) & ~ ( ( a4
[ 3 ] >> 6 ) & ( a4
[ 3 ] << 58 ) ) | ~ ( ( a4
[ 3 ] >> 6 ) & ( a4
[ 3 ] << 58 ) ) & ( a4
[ 3 ] >> 6 ) ) & a4
[ 4 ] ) | ~ ( ( ( a4
[ 3 ] << 58 ) & ~ ( ( a4
[ 3 ] >> 6 ) & ( a4
[ 3 ] << 58 ) ) | ~ ( ( a4
[ 3 ] >> 6 ) & ( a4
[ 3 ] << 58 ) ) & ( a4
[ 3 ] >> 6 ) ) & a4
[ 4 ] ) & ( ( a4
[ 3 ] << 58 ) & ~ ( ( a4
[ 3 ] >> 6 ) & ( a4
[ 3 ] << 58 ) ) | ~ ( ( a4
[ 3 ] >> 6 ) & ( a4
[ 3 ] << 58 ) ) & ( a4
[ 3 ] >> 6 ) ) ; a4
[ 4 ] = a4
[ 5 ] & ~ ( ( ( a4
[ 4 ] << 52 ) & ~ ( ( a4
[ 4 ] >> 12 ) & ( a4
[ 4 ] << 52 ) ) | ~ ( ( a4
[ 4 ] >> 12 ) & ( a4
[ 4 ] << 52 ) ) & ( a4
[ 4 ] >> 12 ) ) & a4
[ 5 ] ) | ~ ( ( ( a4
[ 4 ] << 52 ) & ~ ( ( a4
[ 4 ] >> 12 ) & ( a4
[ 4 ] << 52 ) ) | ~ ( ( a4
[ 4 ] >> 12 ) & ( a4
[ 4 ] << 52 ) ) & ( a4
[ 4 ] >> 12 ) ) & a4
[ 5 ] ) & ( ( a4
[ 4 ] << 52 ) & ~ ( ( a4
[ 4 ] >> 12 ) & ( a4
[ 4 ] << 52 ) ) | ~ ( ( a4
[ 4 ] >> 12 ) & ( a4
[ 4 ] << 52 ) ) & ( a4
[ 4 ] >> 12 ) ) ; a4
[ 5 ] = a4
[ 6 ] & ~ ( ( ( a4
[ 5 ] << 46 ) & ~ ( ( a4
[ 5 ] >> 18 ) & ( a4
[ 5 ] << 46 ) ) | ~ ( ( a4
[ 5 ] >> 18 ) & ( a4
[ 5 ] << 46 ) ) & ( a4
[ 5 ] >> 18 ) ) & a4
[ 6 ] ) | ~ ( ( ( a4
[ 5 ] << 46 ) & ~ ( ( a4
[ 5 ] >> 18 ) & ( a4
[ 5 ] << 46 ) ) | ~ ( ( a4
[ 5 ] >> 18 ) & ( a4
[ 5 ] << 46 ) ) & ( a4
[ 5 ] >> 18 ) ) & a4
[ 6 ] ) & ( ( a4
[ 5 ] << 46 ) & ~ ( ( a4
[ 5 ] >> 18 ) & ( a4
[ 5 ] << 46 ) ) | ~ ( ( a4
[ 5 ] >> 18 ) & ( a4
[ 5 ] << 46 ) ) & ( a4
[ 5 ] >> 18 ) ) ; a4
[ 6 ] = a4
[ 7 ] & ~ ( ( ( a4
[ 6 ] << 40 ) & ~ ( ( a4
[ 6 ] >> 24 ) & ( a4
[ 6 ] << 40 ) ) | ~ ( ( a4
[ 6 ] >> 24 ) & ( a4
[ 6 ] << 40 ) ) & ( a4
[ 6 ] >> 24 ) ) & a4
[ 7 ] ) | ~ ( ( ( a4
[ 6 ] << 40 ) & ~ ( ( a4
[ 6 ] >> 24 ) & ( a4
[ 6 ] << 40 ) ) | ~ ( ( a4
[ 6 ] >> 24 ) & ( a4
[ 6 ] << 40 ) ) & ( a4
[ 6 ] >> 24 ) ) & a4
[ 7 ] ) & ( ( a4
[ 6 ] << 40 ) & ~ ( ( a4
[ 6 ] >> 24 ) & ( a4
[ 6 ] << 40 ) ) | ~ ( ( a4
[ 6 ] >> 24 ) & ( a4
[ 6 ] << 40 ) ) & ( a4
[ 6 ] >> 24 ) ) ; a4
[ 7 ] = * a4
& ~ ( ( ( a4
[ 7 ] << 34 ) & ~ ( ( a4
[ 7 ] >> 30 ) & ( a4
[ 7 ] << 34 ) ) | ~ ( ( a4
[ 7 ] >> 30 ) & ( a4
[ 7 ] << 34 ) ) & ( a4
[ 7 ] >> 30 ) ) & * a4
) | ~ ( ( ( a4
[ 7 ] << 34 ) & ~ ( ( a4
[ 7 ] >> 30 ) & ( a4
[ 7 ] << 34 ) ) | ~ ( ( a4
[ 7 ] >> 30 ) & ( a4
[ 7 ] << 34 ) ) & ( a4
[ 7 ] >> 30 ) ) & * a4
) & ( ( a4
[ 7 ] << 34 ) & ~ ( ( a4
[ 7 ] >> 30 ) & ( a4
[ 7 ] << 34 ) ) | ~ ( ( a4
[ 7 ] >> 30 ) & ( a4
[ 7 ] << 34 ) ) & ( a4
[ 7 ] >> 30 ) ) ; v6
= 1 ; } return v6
;
}
將輸入的flag分成8份,化簡找規(guī)律
x = a4[i] << a y = a4[i] >> b (a + b = 64) z = x & ~(x & y) | ~(x & y) & y a4[i] = a4[i+1] & ~(z & a4[i+1]) | ~(z & a4[i+1]) & z
利用python寫出真值表
for x
in range ( 2 ) : for y
in range ( 2 ) : print ( x
, ' ' , y
, ' ' , x
& ~ ( x
& y
) | ~ ( x
& y
) & y
)
直接寫出真值表 異或操作
寫出逆向腳本
#include <iostream> using namespace std
; int main ( ) { unsigned __int64 data
[ 8 ] = { 0x08CD53D0EAE56FDE , 0xE0310C8244BA1FA3 , 0x45B42002CE1B213D , 0x16FDC411224CB2DF , 0x2FD8108A59461BCC , 0x8F6990725EB01982 , 0x9BA5ADE29A2A17D8 , 0x4DEAA99F5D9F6605 } ; for ( int i
= 0 ; i
<= 63 ; ++ i
) { data
[ 7 ] = ( ( data
[ 7 ] ^ data
[ 0 ] ) >> 34 ) ^ ( ( data
[ 7 ] ^ data
[ 0 ] ) << 30 ) ; data
[ 6 ] = ( ( data
[ 6 ] ^ data
[ 7 ] ) >> 40 ) ^ ( ( data
[ 6 ] ^ data
[ 7 ] ) << 24 ) ; data
[ 5 ] = ( ( data
[ 5 ] ^ data
[ 6 ] ) >> 46 ) ^ ( ( data
[ 5 ] ^ data
[ 6 ] ) << 18 ) ; data
[ 4 ] = ( ( data
[ 4 ] ^ data
[ 5 ] ) >> 52 ) ^ ( ( data
[ 4 ] ^ data
[ 5 ] ) << 12 ) ; data
[ 3 ] = ( ( data
[ 3 ] ^ data
[ 4 ] ) >> 58 ) ^ ( ( data
[ 3 ] ^ data
[ 4 ] ) << 6 ) ; data
[ 2 ] = ( ( data
[ 2 ] ^ data
[ 3 ] ) >> 16 ) ^ ( ( data
[ 2 ] ^ data
[ 3 ] ) << 48 ) ; data
[ 1 ] = ( ( data
[ 1 ] ^ data
[ 2 ] ) >> 22 ) ^ ( ( data
[ 1 ] ^ data
[ 2 ] ) << 42 ) ; data
[ 0 ] = ( ( data
[ 0 ] ^ data
[ 1 ] ) >> 28 ) ^ ( ( data
[ 0 ] ^ data
[ 1 ] ) << 36 ) ; } for ( const auto & datum
: data
) { cout
<< hex
<< datum
<< endl
; } return 0 ;
}
拼接結(jié)果可得BJD{easy_logical_algorithm_for_freshman_and_try_to_slove_it_yourself}
總結(jié)
以上是生活随笔 為你收集整理的安恒5月赛BJDCTF3th-逆向 的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔 推薦給好友。