攻防世界進(jìn)階Re(二)

感覺難度越來越大了吃溅,把進(jìn)階題分為幾篇來寫,以便查看鸯檬。

0x00 reverse-box

感覺都是沒有看到過的題型决侈,看了大佬WP,還是不懂喧务。赖歌。。先留著以后再看功茴。
要用GDB命令腳本先放個(gè)鏈接如何寫gdb命令腳本庐冯。

0x01 IgniteMe

這道題就非常的友好了,拖進(jìn)IDA坎穿。


image.png

檢查輸入的前四個(gè)字符為 ' EIS{ ' 最后一個(gè)為 ‘ } ’展父,然后進(jìn)入sub_4011c0() 關(guān)鍵函數(shù)。
這個(gè)函數(shù)就是交換大小寫玲昧,然后異或操作之后看與最后的字符串一不一樣栖茉。


image.png

首先雙擊unk_4420B0選中,按shift+e 把它提取出來(新學(xué)的操作孵延,好舒服奥榔!終于不用手動(dòng)碼了)隙袁。
然后就是寫腳本異或回去得到v4了,在轉(zhuǎn)換大小寫加上 EIS{ 和 } 就是flag了弃榨。
image.png

腳本如下:

a = "GONDPHyGjPEKruv{{pj]X@rF"
xor_string = [ 0x0D, 0x13, 0x17, 0x11, 0x02, 0x01, 0x20, 0x1D, 0x0C, 0x02, 
               0x19, 0x2F, 0x17, 0x2B, 0x24, 0x1F, 0x1E, 0x16, 0x09, 0x0F, 
               0x15, 0x27, 0x13, 0x26, 0x0A, 0x2F, 0x1E, 0x1A, 0x2D, 0x0C, 
               0x22, 0x04]
s = []
flag = ''
for i in range(len(a)):
    s.append(ord(a[i])^ xor_string[i])
for i in range(len(s)):
    s[i] -= 72
    s[i] = s[i]^0x55
for i in s:
    flag += chr(i)
print(flag.lower())

0x02 srm-50

這道題感覺我是非預(yù)期解啊菩收,都不分析什么,正解應(yīng)該是用OD破解找到注冊(cè)碼的鲸睛。我直接拖進(jìn)IDA,F12找到報(bào)錯(cuò)的字符串娜饵,看到if判斷語(yǔ)句,將v11[0],v11[1],v11[2],v11[3],v12,v13…………連續(xù)字符得到就是flag了官辈。箱舞。遍坟。。晴股。愿伴。


image.png

0x03 ReverseMe-120

拖進(jìn)IDA,看到主函數(shù)感覺很簡(jiǎn)單的亞子电湘。我們看到最后只判斷了v13是否與“you_know_how_to_remove_junk_code” 一樣隔节,往上分析v13經(jīng)過了sub_401000()然后與0x25異或。


image.png

跟進(jìn)sub_401000()寂呛,分析不出來是什么怎诫,,贷痪,看了大佬的WP ,這是base64的解密幻妓,還是太菜了,沒有看出特征劫拢。所以將“you_know_how_to_remove_junk_code” 與0x25異或后再base64加密得到flag肉津。


image.png

0x04 CRACKME

運(yùn)行exe,要調(diào)入注冊(cè)碼,隨便輸入有彈窗錯(cuò)誤尚镰。拖進(jìn)IDA,發(fā)現(xiàn)是MFC寫的程序阀圾。參考大佬文章,MessageBoxA函數(shù)是于創(chuàng)建狗唉、顯示并操作一個(gè)消息對(duì)話框的初烘,所以我們找到調(diào)用MessageBoxA的函數(shù)。


image.png

跟進(jìn)sub_401720 和sub_4016E0發(fā)現(xiàn)不了什么分俯,繼續(xù)查看他們的引用肾筐。在這里就可以猜測(cè)這兩個(gè)MessageBoxA一個(gè)是顯示錯(cuò)誤彈窗一個(gè)是正確彈窗。輸入的數(shù)據(jù)經(jīng)過sub_401630()之后才判斷對(duì)錯(cuò)缸剪。所以跟進(jìn)sub_401630()分析吗铐。


image.png

這里看了WP有點(diǎn)不懂,為什么偽隨機(jī)數(shù)種子一直都是1 杏节,偽隨機(jī)數(shù)不變唬渗。繼續(xù)分析 if 里面,就是每隔10個(gè)字符判斷是否相等奋渔。
image.png

這里將一個(gè)很長(zhǎng)的字符串復(fù)制給v2+96镊逝,看WP說v2就是上面的v3,這一點(diǎn)也有些疑惑,沒有看出來嫉鲸。也許是this指針的原因吧撑蒜。接下來這個(gè)長(zhǎng)字符串從第二個(gè)字符開始到330位,每隔10位取出一個(gè)字符。


image.png

腳本如下:
a = ";f1K3{c5:efl21t4;1t1zaxpim9}5+?gtux;=vc9v{v7+buhU{bT=-am2q}=fh[xk{y?xrqe{?}l5-sd2-Mo+:j{9=sY[dalvpx?z3{?no{[k5ll{zjsu5[kfla+r6Zg72o0skq6cGl5cw[=d?3v9q5-vkjSv{4sqtg=f0cz{+jurjfl[tb]lrfF1;2}udhb?0g8{om:T4dh;z:oz-Dn=m=ux;o[gs9{+zqx+sq-dsxctcvykUs2oddrt43pwv:f0;njkrb9los6g0{ih?rqantfx$sslqd:rvqixr;j{?o:sn+[i[yA11;gsmr8lm0?3};+iv+Tf:4Gtv2:-20upi0]7?77=;qzx{m-W;0vtueh]ko8d?=w:fbhd{E:;19?p=k:b+}doht6wpEq-z]2qbV1}dh416qw9:xm[;ed;:ecb-0:ni-s4u2kf6]2wn45amzjrun=ofkx-=hmgo-lz;j909=rmo7xcj4le0hxs[i]-vjl[?o12:sv4upio7ma1hRy7556+57krev:hLQ+1cx65z5v5];6n=[p83;n={zm{k2p"
for i in range(1,330,10):
   print(a[i],end='')

0x05 tt3441810

這道題看不懂座菠,以為是手動(dòng)脫殼狸眼。搜了官方WP,也是一臉懵逼,這是雜項(xiàng)題嗎浴滴?
用IDA或者notepad++打開看到十六進(jìn)制數(shù)拓萌,在這里看到 ‘fl’ ,{ } 等字樣巡莹,然后把一些混淆字符去掉得到flag,還得提交括號(hào)里面的內(nèi)容司志。又看了里面自帶的WP,還是學(xué)到了xxd使用降宅。
flag{poppopret}

image.png

0x06 zorropub

先拖進(jìn)IDA,分析下程序流程骂远,題的意思很簡(jiǎn)單,主要是輸入飲料的數(shù)量和飲料ID經(jīng)過下面函數(shù)在計(jì)算MD5腰根,判斷其MD5是否相等激才。


  v15 = __readfsqword(0x28u);
  seed = 0;
  puts("Welcome to Pub Zorro!!");
  printf("Straight to the point. How many drinks you want?", a2);
  __isoc99_scanf("%d", &v5);
  if ( v5 <= 0 )
  {
    printf("You are too drunk!! Get Out!!", &v5);
    exit(-1);
  }
  printf("OK. I need details of all the drinks. Give me %d drink ids:", (unsigned int)v5);
  for ( i = 0; i < v5; ++i )
  {
    __isoc99_scanf("%d", &v6);   //循環(huán)輸入飲料ID
    if ( v6 <= 16 || v6 > 0xFFFF )  //飲料ID在 [16,65535]范圍內(nèi)。
    {
      puts("Invalid Drink Id.");
      printf("Get Out!!", &v6);
      exit(-1);
    }
    seed ^= v6;   //隨機(jī)種子
  }
  i = seed;
  v9 = 0;
  while ( i )
  {
    ++v9;
    i &= i - 1;
  }
  if ( v9 != 10 )
  {
    puts("Looks like its a dangerous combination of drinks right there.");
    puts("Get Out, you will get yourself killed");
    exit(-1);
  }
  srand(seed);
  MD5_Init((__int64)&v10);
  for ( i = 0; i <= 29; ++i )
  {
    v9 = rand() % 1000;
    sprintf(&s, "%d", v9);
    v3 = strlen(&s);
    MD5_Update((__int64)&v10, (__int64)&s, v3);
    v12[i] = v9 ^ LOBYTE(dword_6020C0[i]);   //LOBYTE()得到一個(gè)16bit數(shù)最低(最右邊)那個(gè)字節(jié)
  }
  v12[i] = 0;
  MD5_Final(v11, &v10);
  for ( i = 0; i <= 15; ++i )
    sprintf(&s1[2 * i], "%02x", (unsigned __int8)v11[i]);
  if ( strcmp(s1, "5eba99aff105c9ff6a1a913e343fec67") )
  {
    puts("Try different mix, This mix is too sloppy");
    exit(-1);
  }
  return printf("\nYou choose right mix and here is your reward: The flag is nullcon{%s}\n", v12);
}

這里我們有兩種思路额嘿,1.爆破MD5瘸恼,2.逆向算法。
1.爆破MD5:
先根據(jù)飲料ID范圍在 [16,65535]册养,和下面check來從中篩選出符合ID的值东帅。

 while ( i )
  {
    ++v9;
    i &= i - 1;
  }
  if ( v9 != 10 )

在使用subprocess庫(kù),(想使用pwntools的球拦,結(jié)果沒有搜到pwntools如何殺死進(jìn)程的函數(shù)靠闭,看了大佬文章才知道還有subprocess的),將滿足ID的數(shù)使用subprocess里的communicate()帶進(jìn)去試一試坎炼,看能否返回flag愧膀。
腳本如下:

#!/usr/bin/python
# -*- coding: utf-8 -*-
from subprocess import *

#這里是找出符合條件的數(shù)
a=[]
for i in range(16,65535):
    v9 = 0
    s=i
    while i:
        v9 +=1
        i &= i-1
    if v9 == 10:
        a.append(s)
#循環(huán)輸入符合條件的數(shù),爆破flag
for i in a:
    proc = Popen(['./zorro_bin'],stdin=PIPE,stdout=PIPE)
    out = proc.communicate(('1\n%s\n' % i).encode('utf-8'))[0]#這里communicate返回的是一個(gè)元組谣光,但是元組只有一個(gè)元素檩淋,所以要加上偏移0。
    if "nullcon".encode('utf-8') in out:
      print(out)
      print(i)
image.png

2.逆向算法
這是在官方WP復(fù)制的萄金。利用libc.so.6動(dòng)態(tài)鏈接庫(kù)得到生成的偽隨機(jī)數(shù)蟀悦。然后對(duì)著IDA的函數(shù)復(fù)現(xiàn)一遍。得到結(jié)果也是輸入59306的時(shí)候正確氧敢。

import ctypes
import os
import sys
import hashlib
libsystem = ctypes.CDLL('libc.so.6')
# Extracted by hand
encryption_key = [
    0x03C8, 0x0032, 0x02CE, 0x0302, 0x007F,
    0x01B8, 0x037E, 0x0188, 0x0349, 0x027F,
    0x005E, 0x0234, 0x0354, 0x01A3, 0x0096,
    0x0340, 0x0128, 0x02FC, 0x0300, 0x028E,
    0x0126, 0x001B, 0x032A, 0x02F5, 0x015F,
    0x0368, 0x01EB, 0x0079, 0x011D, 0x024E
]
need_md5 = '5eba99aff105c9ff6a1a913e343fec67'
mc = 0
while True:
    for drink_id_count in range(17, 0xFFFE):
        mc += 1
        if mc % 1000 == 0:
            sys.stdout.write('.')
            sys.stdout.flush()
        for counter in range(5):
            input_1 = counter
            seed = 0
            drink_ids = []
            for x in range(input_1):
                drink_id = drink_id_count
                drink_ids.append(drink_id)
                if drink_id <= 16 or drink_id > 0xFFFF:
                    continue
                else:
                    seed ^= drink_id
            count = seed
            some_num = 0
            while count > 1:
                some_num += 1
                count &= (count - 1)
            if some_num != 10:
                continue
            else:
                pass
            libsystem.srand(seed)
            flag = ""
            h = hashlib.md5()
            for x in range(30):
                ran = libsystem.rand()
                rand_number = ran % 1000
                h.update("%d" % rand_number)
                flag += chr((rand_number ^ encryption_key[x])&0xFF)#LOBYTE()得到一個(gè)16bit數(shù)最低(最右邊)那個(gè)字節(jié)日戈,所以   & 0xff
            if h.hexdigest() == need_md5:
                print "\nHash -> %s" % h.hexdigest()
                print "Found it! Drinks:%d, Drink IDs:%s" % (counter, drink_ids)
                raw_input()

0x07 Reversing-x64Elf-100

IDA打開,主函數(shù)福稳。分析得到主要邏輯函數(shù)為sub_4006FD(),非常簡(jiǎn)單的邏輯涎拉,寫腳本得到flag。

signed __int64 __fastcall sub_4006FD(__int64 a1)
{
  signed int i; // [rsp+14h] [rbp-24h]
  const char *v3; // [rsp+18h] [rbp-20h]
  const char *v4; // [rsp+20h] [rbp-18h]
  const char *v5; // [rsp+28h] [rbp-10h]

  v3 = "Dufhbmf";
  v4 = "pG`imos";
  v5 = "ewUglpt";
  for ( i = 0; i <= 11; ++i )
  {
    if ( (&v3)[i % 3][2 * (i / 3)] - *(char *)(i + a1) != 1 )
      return 1LL;
  }
  return 0LL;
}
腳本如下:
arr = [
       ['D','u','f','h','b','m','f'],
       ['p','G','`','i','m','o','s'],
       ['e','w','U','g','l','p','t']
      ]
for i in range(12):
    key = arr[i%3][2*int(i/3)] 
    print(chr(ord(key)-1),end='')
    

0x08 gametime

這道題主要靠細(xì)心的圆,先運(yùn)行一下看看鼓拧,在拖進(jìn)IDA,分析下邏輯。這個(gè)游戲就是靠手快越妈,剛好出現(xiàn)規(guī)定字符時(shí)季俩,按一下對(duì)應(yīng)字符進(jìn)入下一關(guān),越來越快梅掠,這單身一輩子也沒有這手速啊酌住。。所以拖進(jìn)OD,找到些關(guān)鍵跳轉(zhuǎn)下斷點(diǎn)阎抒,耐心的調(diào)試耐心的調(diào)試耐心的調(diào)試耐心的調(diào)試酪我,就出來key了。

這里總結(jié)下OD的使用:

  • 找到關(guān)鍵字符且叁,在其上方第一個(gè)跳轉(zhuǎn)一般為關(guān)鍵跳轉(zhuǎn)都哭,越過正確字符的跳轉(zhuǎn)為關(guān)鍵跳轉(zhuǎn)。
  • 在關(guān)鍵跳轉(zhuǎn)處下斷點(diǎn)逞带,運(yùn)行到斷點(diǎn)時(shí)看將要跳轉(zhuǎn)到哪里去欺矫,在判斷是否跳轉(zhuǎn),比如有幾個(gè)跳轉(zhuǎn)都將向同一個(gè)地址跳轉(zhuǎn)展氓,那么這個(gè)跳轉(zhuǎn)就改成不跳轉(zhuǎn)穆趴,因?yàn)橛螒虺鲥e(cuò)有一點(diǎn)錯(cuò)誤就退出,所以這里一定是指向錯(cuò)誤的輸出函數(shù)遇汞,正確的只有一條路未妹,不可能有多個(gè)跳轉(zhuǎn)指向它。
  • 遇到JMP跳轉(zhuǎn)一般不要改勺疼,因?yàn)檫@個(gè)是無條件跳轉(zhuǎn)教寂,無論你輸入的正確與否,它都將跳轉(zhuǎn)执庐。
  • 出現(xiàn)需要循環(huán)運(yùn)行時(shí)酪耕,不用一個(gè)個(gè)的按F8,在跳轉(zhuǎn)的下面一行下斷點(diǎn)轨淌,然后F9直接運(yùn)行迂烁,將會(huì)斷在剛剛下斷點(diǎn)處。
  • 邊調(diào)試邊看運(yùn)行結(jié)果递鹉,看是否正確輸出盟步。
image.png

0x09 easyre-153

首先UPX脫殼。IDA打開躏结,看到pipe()和fork()却盘。
pipe函數(shù)可用于創(chuàng)建一個(gè)管道,以實(shí)現(xiàn)進(jìn)程間的通信。
fork函數(shù)通過系統(tǒng)調(diào)用創(chuàng)建一個(gè)與原來進(jìn)程幾乎完全相同的進(jìn)程黄橘,其返回值是進(jìn)程號(hào)兆览。

這里的邏輯就是輸入一個(gè)進(jìn)程號(hào)要與之前的進(jìn)程號(hào)相等。就顯示正確塞关。
image.png
  v8 = __readgsdword(0x14u);
  pipe(pipedes);
  v5 = fork();
  if ( !v5 )
  {
    puts("\nOMG!!!! I forgot kid's id");
    write(pipedes[1], "69800876143568214356928753", 0x1Du);
    puts("Ready to exit     ");
    exit(0);
  }
  read(pipedes[0], &buf, 0x1Du);
  __isoc99_scanf("%d", &v6);
  if ( v6 == v5 )
  {
    if ( (*(_DWORD *)((_BYTE *)lol + 3) & 0xFF) == 204 )
    {
      puts(":D");
      exit(1);
    }
    printf("\nYou got the key\n ");
    lol(&buf);
  }
  wait(0);
  return 0;
}

但是這里就算輸入正確抬探,lol函數(shù)也會(huì)返回 'flag_is_not_here',所以我們需要使用IDA動(dòng)態(tài)調(diào)試
去修改匯編改變跳轉(zhuǎn)得到flag,之前的進(jìn)程號(hào)也可以隨便輸然后改變后面的關(guān)鍵跳轉(zhuǎn)即可帆赢。

image.png

得到flag,要加上RCTF小压。太坑了,我以為我的不是flag,看了WP才知道椰于。
image.png

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末怠益,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子瘾婿,更是在濱河造成了極大的恐慌溉痢,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,590評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件憋他,死亡現(xiàn)場(chǎng)離奇詭異孩饼,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)竹挡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門镀娶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人揪罕,你說我怎么就攤上這事梯码。” “怎么了好啰?”我有些...
    開封第一講書人閱讀 169,301評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵轩娶,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我框往,道長(zhǎng)鳄抒,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,078評(píng)論 1 300
  • 正文 為了忘掉前任椰弊,我火速辦了婚禮许溅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘秉版。我一直安慰自己贤重,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評(píng)論 6 398
  • 文/花漫 我一把揭開白布清焕。 她就那樣靜靜地躺著并蝗,像睡著了一般祭犯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上滚停,一...
    開封第一講書人閱讀 52,682評(píng)論 1 312
  • 那天盹憎,我揣著相機(jī)與錄音,去河邊找鬼铐刘。 笑死,一個(gè)胖子當(dāng)著我的面吹牛影晓,可吹牛的內(nèi)容都是我干的镰吵。 我是一名探鬼主播,決...
    沈念sama閱讀 41,155評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼挂签,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼疤祭!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起饵婆,我...
    開封第一講書人閱讀 40,098評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤勺馆,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后侨核,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體草穆,經(jīng)...
    沈念sama閱讀 46,638評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評(píng)論 3 342
  • 正文 我和宋清朗相戀三年搓译,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了悲柱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,852評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡些己,死狀恐怖豌鸡,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情段标,我是刑警寧澤涯冠,帶...
    沈念sama閱讀 36,520評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站逼庞,受9級(jí)特大地震影響蛇更,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜赛糟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評(píng)論 3 335
  • 文/蒙蒙 一械荷、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧虑灰,春花似錦吨瞎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)字旭。三九已至,卻和暖如春崖叫,著一層夾襖步出監(jiān)牢的瞬間遗淳,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工心傀, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留屈暗,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,279評(píng)論 3 379
  • 正文 我出身青樓脂男,卻偏偏與公主長(zhǎng)得像养叛,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子宰翅,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容