日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

NCTF RE

發布時間:2023/12/15 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 NCTF RE 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

16bit

16進制的匯編閱讀訓練。匯編賊煩,還好師傅手下留情,邏輯段一點不復雜,拖進ida//ida牛逼,查看start函數,跟到sub_100ac下面,看的出來這個是主函數

mov di, 3

call sub_10115

mov di, 24h ; ‘$’

call sub_10123

mov bx, 24h ; ‘$’//輸入

add bx, 1

cmp byte ptr [bx], 23h ; ‘#’//不是35個字符gg

jnz short loc_100DD

之后跳轉這兒

mov di, 26h ; ‘&’

call sub_100F9

mov si, 76h ; ‘v’

mov dx, 23h ; ‘#’

call sub_100E4//這個是對比,對比輸入的跟偏移值位76h的地方的是否相等,相等ok

test ax, ax

jnz short loc_100DD

其中sub_100f9是解釋器

進去loc_100FE:

mov al, [bx+si]

mov dl, al

mov cl, 3

shr al, cl//input[i]>>3

mov cl, 5

shl dl, cl//input[i]<<5

xor al, dl//之后抑或操作下

mov [bx+si], al

inc si

cmp si, 23h ; ‘#’

jnz short loc_100FE

之后很明顯了,逆向的話就是將原本存在內存中用來對比的//就是加密好的那個先右移3位,再左移5位,之后抑或,貼逆向代碼

#include<stdio.h>
int main(){

int a[35]={0xc9,0x68,0x8a,0xc8,0x6f,0x7,0x6,0xf,0x7,0xc6,0xeb,0x86,0x6e,0x6e,0x66,0xad,0x4c,0x8d,0xac,0xeb,0x26,0x6e,0xeb,0xcc,0xae,0xcd,0x8c,0x86,0xad,0x66,0xcd,0x8e,0x86,0x8d,0xaf}; for(int i=0;i<35;i++){int front5=0;int last3=0;front5=a[i]<<3;last3=a[i]>>5;a[i]=front5 ^ last3;printf("%c",a[i]); }

2.后門

大水題,找函數,按r,注意xx=0,x0=x,之后就是個換位操作,結束。

3.box

王師傅的box,一開始沒做出來的,因為找不到那個數組中的20,后來跟隊友閑扯發現有段函數不能偽c,懷疑有貓膩,于是讀匯編,貼匯編:

sub_400EB9 proc near ; DATA XREF:.init_array:0000000000601E10↓o

.text:0000000000400EB9

.text:0000000000400EB9 var_4 = dword ptr -4

.text:0000000000400EB9

.text:0000000000400EB9 ; __unwind {

.text:0000000000400EB9 push rbp

.text:0000000000400EBA mov rbp, rsp

.text:0000000000400EBD mov [rbp+var_4], 0

.text:0000000000400EC4 jmp short loc_400EE6

.text:0000000000400EC6 ;---------------------------------------------------------------------------

.text:0000000000400EC6

.text:0000000000400EC6 loc_400EC6: ; CODE XREF:sub_400EB9+34↓j

.text:0000000000400EC6 mov eax, [rbp+var_4]

.text:0000000000400EC9 cdqe

.text:0000000000400ECB movzx edx, byte_6020A0[rax]

.text:0000000000400ED2 mov eax, [rbp+var_4]

.text:0000000000400ED5 xor edx, eax

.text:0000000000400ED7 mov eax, [rbp+var_4]

.text:0000000000400EDA cdqe

.text:0000000000400EDC mov byte_6020A0[rax], dl

.text:0000000000400EE2 add [rbp+var_4], 1

.text:0000000000400EE6

.text:0000000000400EE6 loc_400EE6: ; CODE XREF:sub_400EB9+B↑j

.text:0000000000400EE6 cmp [rbp+var_4], 191

.text:0000000000400EED jle short loc_400EC6

.text:0000000000400EEF push rax

.text:0000000000400EF0 xor rax, rax

.text:0000000000400EF3 jz short loc_400EF9

.text:0000000000400EF5 add rsp, 40

.text:0000000000400EF9

.text:0000000000400EF9 loc_400EF9: ; CODE XREF:sub_400EB9+3A↑j

.text:0000000000400EF9 pop rax

.text:0000000000400EFA nop

.text:0000000000400EFB pop rbp

.text:0000000000400EFC retn

讀了下,發現是對那個后來比較的那個數組進行加密,加密方法是a[i]=a[i]^I;

之后加密完得到地圖:

//為了好看我把20改成2了,這樣對齊

//a,b,c是三個特殊的起始點,后面會寫

之后看主函數,最上面是那個神奇(可惡)的兔子函數,里面會有個sub_400796(),點進去發現是個初始化點坐標//就是我標出的a,b,c三點的初始坐標

之后,在主函數里面會有四個函數,分別對應4,5,W,0的情況,鑒于差不多,我就只發4的情況的那個函數的解析://那些變量被我用n健換成了a,b,i,j,n,m,看著舒服

_int64 sub_400C62()

{

__int64 result; // rax

result = (unsigned __int8)byte_6020A0[16 * i - 1 + j];

if( (_BYTE)result != 8 )

if ( j - 1 != m || i != n )

{if ( j - 1 == a && i == b ){if ( byte_6020A0[16 * b - 1 + a] == 8 )++j; elsesub_400A1C(&a); }

else if ( byte_6020A0[16 * n - 1 + m] == 8 )

{++j; }

else

{sub_400A1C(&m); }result= (unsigned int)(j-- - 1);

}

return result;

}

之后三個類似,最后得出4左,5下,W上,0右

這個是個推箱子游戲

玩吧,之后把操作情況交上去就可以出flag了

4.基本操作:

直接看main

puts(“Input flag:”);

__isoc99_scanf("%64s", input); // 輸入的是個樹

i =0;

sub_400666(0); // 樹的前序遍歷

if(!strcmp(&s1, “bcec8d7dcda25d91ed3e0b720cbb6cf202b09fedbc3e017774273ef5d5581794”))

{

memset(&s1, 0, 0x80uLL);

i= 0;

sub_4006BE(0, 0LL); // 樹的中序遍歷

if ( !strcmp(&s1,“7d8dcdcaed592e1dcb07e02c36bcb2f0bf9e0bdcb0e13777237e25fd48515974”) )

printf("TQL! TQL! flag: nctf{%s}\n", input);

else

puts("Emmmm.....");

result = 0LL;

}

else

{

puts(“GG!”);

result = 0LL;

}

return result;

}

然后就很清楚了,這個是個給了你二叉樹前序遍歷下來后的字符串跟中序遍歷的字符串

之后注意一個這個輸入的是個字符串,所以畫下來是個標準二叉樹,標準的!!!所以每個節點都是有左右子樹的!,64個字符,就是6層帶最后還有一個連著,之后開始就很舒服了,就根據前序遍歷的規則挨個寫//其實這個是a掉后看著樹才想到的,一開始做的時候,感謝我們隊的密碼手幫我手算出來。//都快算哭了,特別是知道可以這么玩后。

所以可以寫個程序,輸出64之內的標準二叉樹前序遍歷之后的輸出順序,之后跟題目中的對照,再得到flag。

貼代碼

#include

using namespace std;

void pro(int i)

{

if(i<=63){cout<<i<<"";pro(2*i+1);pro(2*i+2);

}

else

return;

}

int main()

{

pro(0);

}

得到輸出順序,對比得flag
還有題wcyvm,不知道為什么指令集好像搞崩掉了,先鴿著。

Ceypto

Math of homura

放到vscode中看源碼,先貼源碼

import gmpy2

import random

import GetFlag

c =random.randint(2 ** 127,2**128)

c = gmpy2.mpfr?

print “Homura sent some message afterdisappearing.”

print “But it was encoded and no onecan understand it.”

print “Fortunately you findsomething:”

print c

print “May be it will be useful.”

flag = GetFlag.getFlag()

mess = GetFlag.message()

i = 1

print “Here is the encodedmessage”

for ch in mess:

b=random.randint(2 ** 127,2**128)b= gmpy2.mpfr(b)a= gmpy2.root(b*b+c*c,2)x= gmpy2.mpfr((gmpy2.mpfr(ord(ch))/128.0)*(a))y= gmpy2.root((b*b-((b*b)/(a*a))*(x*x)),2)l1= gmpy2.root((((x+c)**2)+(y**2)),2)l2= gmpy2.root((((x-c)**2)+(y**2)),2)print"l1[%d]:"%iprintl1print"l2[%d]:"%iprintl2i+=1

print “Now tell me what homurasaid?”

ans = raw_input()

if ans == mess:

printflag

else:

print"No you did not understand what homura said."

然后數學計算嘛,算下來是

L1=a+ch*c/128

L2=a-ch*c/128

之后l1-l2就是ch*c/64,c是給出了的

然后將它輸出的東西進行操作,得到ascll碼表,不過注意的是它這個居然是變化的!!!一開始以為是靜態不變的直接用上次得到的數據逆向結果答案錯了,所以要用pwn的思路。。。

之后還有個坑就是,它算下來不是精確的整數,會有微小偏差,如果直接變成字符會報錯,所以還要+0.5后去除小數,貼代碼

from pwn import *

r = remote(‘ctfgame.acdxvfsvd.net’, 30002)

r.recvuntil(‘Your Token:\n’)
r.sendline(‘a8x69OokWdZJrRAyfCzhKFSiu6tlS8bg’)
r.recvuntil(‘something:\n’)
c=r.recvline()

payload =’’

r.recvuntil(‘message\n’)
for i in range(261):
a = r.recvline(keepends=True)
l1 = r.recvline(keepends=True)
a = r.recvline(keepends=True)
l2 = r.recvline(keepends=True)
k=float(l1)-float(l2)
k=k/float?*64+0.5

ch=int(k) payload+=chr(ch)

r.recvuntil(‘said?\n’)
r.sendline(payload)
r.interactive()

EAX:累加(Accumulator)寄存器,常用于函數返回值
EBX:基址(Base)寄存器,以它為基址訪問內存
ECX:計數器(Counter)寄存器,常用作字符串和循環操作中的計數器
EDX:數據(Data)寄存器,常用于乘除法和I/O指針
ESI:源變址寄存器
DSI:目的變址寄存器
ESP:堆棧(Stack)指針寄存器,指向堆棧頂部
EBP:基址指針寄存器,指向當前堆棧底部
EIP:指令寄存器,指向下一條指令的地址
call指令隱含操作push EIP,ret指令隱含操作 pop EIP

總結

以上是生活随笔為你收集整理的NCTF RE的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。